WooCommerce Docs: Delete posts when it removed from the manifest (#39395)
This commit is contained in:
parent
0d8d824b47
commit
b14653ede0
|
@ -10,7 +10,7 @@
|
|||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/local-development.md",
|
||||
"id": "1a3672ea88756c6d00a3b3baa3f7481b361c8a1e",
|
||||
"links": {
|
||||
"./installation/install-plugin.md": "16d17f790732fcdc0560d2ae24490be272e2fe39"
|
||||
"./installation/install-plugin.md": "6c7bb21cb195798a444844fef0ff79aacff86de1"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -38,7 +38,7 @@
|
|||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/troubleshooting/what-went-wrong.md",
|
||||
"id": "e2f590a5994fada97bdbdcac751e8bc441530868",
|
||||
"links": {
|
||||
"../../testing/unit-tests.md": "079882c5dbbc1da106e3acc8df4102643e6c2f59"
|
||||
"../../testing/unit-tests.md": "6f1b9c74de42a10cf4c77c2843e0fbdf1ff46316"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -67,5 +67,5 @@
|
|||
"categories": []
|
||||
}
|
||||
],
|
||||
"hash": "00958a305458e9fc9191eb56309ab88ab459f10d059cad5fbb74824f9e0d4010"
|
||||
"hash": "c727b2b8092cae90356d44d2803e5c70688b548b474467c994f55431055fbb69"
|
||||
}
|
|
@ -118,10 +118,15 @@ class DocsStore {
|
|||
/**
|
||||
* Delete a docs post
|
||||
*
|
||||
* @param int $post_id The post ID to delete.
|
||||
* @param int $doc_id The ID to delete from a post's entry in the manifest.
|
||||
*/
|
||||
public static function delete_docs_post( $post_id ) {
|
||||
return wp_delete_post( $post_id );
|
||||
public static function delete_docs_post( $doc_id ) {
|
||||
$post = self::get_post( $doc_id );
|
||||
if ( null !== $post ) {
|
||||
return wp_delete_post( $post->ID, true );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,9 +75,12 @@ class ManifestJob {
|
|||
\ActionScheduler_Logger::instance()->log( $action_id, "Manifest hash changed: `$hash`, processing manifest." );
|
||||
} else {
|
||||
\ActionScheduler_Logger::instance()->log( $action_id, 'No previous manifest found, processing manifest.' );
|
||||
$existing_manifest = null;
|
||||
}
|
||||
|
||||
$doc_ids = ManifestProcessor::process_manifest( $json, $action_id );
|
||||
ManifestProcessor::process_manifest( $json, $action_id, $existing_manifest );
|
||||
|
||||
$doc_ids = ManifestProcessor::collect_doc_ids_from_manifest( $json );
|
||||
$relative_links = RelativeLinkParser::extract_links_from_manifest( $json );
|
||||
|
||||
foreach ( $doc_ids as $doc_id ) {
|
||||
|
@ -92,6 +95,7 @@ class ManifestJob {
|
|||
\ActionScheduler_Logger::instance()->log( $action_id, "During link replacement, post was not found for doc: `$doc_id`" );
|
||||
}
|
||||
}
|
||||
|
||||
Data\ManifestStore::update_manifest( $manifest_url, $json );
|
||||
} else {
|
||||
\ActionScheduler_Logger::instance()->log( $action_id, "Manifest hash unchanged: `$hash`, skipping manifest." );
|
||||
|
|
|
@ -15,11 +15,13 @@ class ManifestProcessor {
|
|||
*
|
||||
* @param Object $manifest The manifest to process.
|
||||
* @param int $logger_action_id The logger action ID.
|
||||
* @param Object $previous_manifest The previous manifest.
|
||||
*/
|
||||
public static function process_manifest( $manifest, $logger_action_id ) {
|
||||
$doc_ids = array();
|
||||
self::process_categories( $manifest['categories'], $logger_action_id, $doc_ids );
|
||||
return $doc_ids;
|
||||
public static function process_manifest( $manifest, $logger_action_id, $previous_manifest = null ) {
|
||||
if ( $previous_manifest ) {
|
||||
PostRemover::remove_deleted_posts( $manifest, $previous_manifest, $logger_action_id );
|
||||
}
|
||||
self::process_categories( $manifest['categories'], $logger_action_id );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,10 +29,9 @@ class ManifestProcessor {
|
|||
*
|
||||
* @param array $categories The categories to process.
|
||||
* @param int $logger_action_id The logger action ID.
|
||||
* @param array $doc_ids An array to maintain a list of created/updated post IDs.
|
||||
* @param int $parent_id The parent ID.
|
||||
*/
|
||||
private static function process_categories( $categories, $logger_action_id, &$doc_ids, $parent_id = 0 ) {
|
||||
private static function process_categories( $categories, $logger_action_id, $parent_id = 0 ) {
|
||||
foreach ( $categories as $category ) {
|
||||
$term = CategoryCreator::create_or_update_category_from_manifest_entry( $category, $parent_id );
|
||||
|
||||
|
@ -48,19 +49,33 @@ class ManifestProcessor {
|
|||
$content = wp_remote_retrieve_body( $response );
|
||||
|
||||
$post_id = PostCreator::create_or_update_post_from_manifest_entry( $post, $content, $category['category_title'], $logger_action_id );
|
||||
$doc_id = DocsStore::get_doc_id_by_post_id( $post_id );
|
||||
|
||||
// Add the post ID to the list of post IDs.
|
||||
$doc_ids[] = $doc_id;
|
||||
|
||||
wp_set_post_categories( $post_id, array( $term['term_id'] ) );
|
||||
}
|
||||
|
||||
// Process any sub-categories.
|
||||
if ( ! empty( $category['categories'] ) ) {
|
||||
self::process_categories( $category['categories'], $logger_action_id, $doc_ids, $term['term_id'] );
|
||||
self::process_categories( $category['categories'], $logger_action_id, $term['term_id'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recusively collect post IDs from a manifest.
|
||||
*
|
||||
* @param Object $manifest The manifest to process.
|
||||
*/
|
||||
public static function collect_doc_ids_from_manifest( $manifest ) {
|
||||
$doc_ids = array();
|
||||
foreach ( $manifest['categories'] as $category ) {
|
||||
foreach ( $category['posts'] as $post ) {
|
||||
$doc_ids[] = $post['id'];
|
||||
}
|
||||
$subcategory_ids = self::collect_doc_ids_from_manifest( $category );
|
||||
$doc_ids = array_merge( $doc_ids, $subcategory_ids );
|
||||
}
|
||||
|
||||
return $doc_ids;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace WooCommerceDocs\Manifest;
|
||||
|
||||
use WooCommerceDocs\Data\DocsStore;
|
||||
|
||||
/**
|
||||
* Class Remover
|
||||
*
|
||||
* Remove posts that are no longer in the manifest.
|
||||
*
|
||||
* @package WooCommerceDocs\Manifest
|
||||
*/
|
||||
class PostRemover {
|
||||
/**
|
||||
* Remove posts that are no longer in the manifest.
|
||||
*
|
||||
* @param Object $manifest The manifest to process.
|
||||
* @param Object $previous_manifest The previous manifest.
|
||||
* @param int $logger_action_id The logger action ID.
|
||||
*/
|
||||
public static function remove_deleted_posts( $manifest, $previous_manifest, $logger_action_id ) {
|
||||
$doc_ids_to_delete = self::get_doc_ids_to_delete( $manifest, $previous_manifest );
|
||||
|
||||
foreach ( $doc_ids_to_delete as $doc_id ) {
|
||||
\ActionScheduler_Logger::instance()->log( $logger_action_id, 'Removing post deleted post with document id: ' . $doc_id );
|
||||
DocsStore::delete_docs_post( $doc_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of doc IDs to delete.
|
||||
*
|
||||
* @param Object $manifest The manifest to process.
|
||||
* @param Object $previous_manifest The previous manifest.
|
||||
*/
|
||||
public static function get_doc_ids_to_delete( $manifest, $previous_manifest ) {
|
||||
$manifest_doc_ids = ManifestProcessor::collect_doc_ids_from_manifest( $manifest );
|
||||
$previous_manifest_doc_ids = ManifestProcessor::collect_doc_ids_from_manifest( $previous_manifest );
|
||||
|
||||
return array_diff( $previous_manifest_doc_ids, $manifest_doc_ids );
|
||||
}
|
||||
}
|
|
@ -122,4 +122,18 @@ class ManifestProcessorTest extends WP_UnitTestCase {
|
|||
$edit_url_what_went_wrong_post = DocsStore::get_edit_url_from_docs_post( $what_went_wrong_post->ID, 'edit_url', true );
|
||||
$this->assertEquals( 'https://example.com/edit/get-started/troubleshooting/what-went-wrong.md', $edit_url_what_went_wrong_post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test collecting doc IDs from a manifest.
|
||||
*/
|
||||
public function test_collect_doc_ids_from_manifest() {
|
||||
$manifest = json_decode( file_get_contents( __DIR__ . '/fixtures/manifest.json' ), true );
|
||||
$doc_ids = ManifestProcessor::collect_doc_ids_from_manifest( $manifest );
|
||||
|
||||
$this->assertEquals( 4, count( $doc_ids ) );
|
||||
$this->assertContains( 'c068ce54044fa44c760a69bd71ef21274f2a5a37', $doc_ids );
|
||||
$this->assertContains( 'fb59bd01dda7b090e5b0a557948e155a6b679d6a', $doc_ids );
|
||||
$this->assertContains( '1f88c4d039e72c059c928ab475ad1ea0a02c8abb', $doc_ids );
|
||||
$this->assertContains( '120770c899215a889246b47ac883e4dda1f97b8b', $doc_ids );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace WooCommerceDocs\Tests\Manifest;
|
||||
|
||||
use WP_UnitTestCase;
|
||||
use WooCommerceDocs\Manifest\PostRemover;
|
||||
|
||||
|
||||
/**
|
||||
* Class PostRemoverTest
|
||||
*
|
||||
* @package WooCommerceDocs\Tests\Manifest
|
||||
*/
|
||||
class PostRemoverTest extends WP_UnitTestCase {
|
||||
/**
|
||||
* Test getting doc IDs to delete.
|
||||
*/
|
||||
public function test_get_doc_ids_to_delete() {
|
||||
// Test identical manifests that should return no doc IDs to delete.
|
||||
$manifest = json_decode( file_get_contents( __DIR__ . '/fixtures/manifest.json' ), true );
|
||||
$previous_manifest = json_decode( file_get_contents( __DIR__ . '/fixtures/manifest.json' ), true );
|
||||
$doc_ids_to_delete = PostRemover::get_doc_ids_to_delete( $manifest, $previous_manifest );
|
||||
|
||||
$this->assertEquals( 0, count( $doc_ids_to_delete ) );
|
||||
|
||||
// Test a post removed by adding a post to the previous_manifest.
|
||||
$updated_previous_manifest = $manifest;
|
||||
$updated_previous_manifest['categories'][0]['posts'][] = array(
|
||||
'id' => '123456789',
|
||||
'post_title' => 'Test Post Title',
|
||||
);
|
||||
|
||||
$doc_ids_to_delete = PostRemover::get_doc_ids_to_delete( $manifest, $updated_previous_manifest );
|
||||
|
||||
$this->assertEquals( 1, count( $doc_ids_to_delete ) );
|
||||
$this->assertContains( '123456789', $doc_ids_to_delete );
|
||||
}
|
||||
}
|
|
@ -73,6 +73,7 @@ export const generateManifestCommand = new Command( 'create' )
|
|||
const manifestWithLinks = await processMarkdownLinks(
|
||||
manifest,
|
||||
absoluteRootDir,
|
||||
absoluteSubDir,
|
||||
projectName
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { generateManifestFromDirectory } from '../generate-manifest';
|
||||
import { processMarkdownLinks } from '../markdown-links';
|
||||
|
||||
describe( 'processMarkdownLinks', () => {
|
||||
const dir = path.join( __dirname, './fixtures/example-docs' );
|
||||
const rootDir = path.join( __dirname, './fixtures' );
|
||||
|
||||
it( 'should add the correct relative links to a manifest', async () => {
|
||||
// generate the manifest from fixture directory
|
||||
const manifest = await generateManifestFromDirectory(
|
||||
rootDir,
|
||||
dir,
|
||||
'example-docs',
|
||||
'https://example.com',
|
||||
'https://example.com/edit'
|
||||
);
|
||||
|
||||
const manifestWithLinks = await processMarkdownLinks(
|
||||
manifest,
|
||||
rootDir,
|
||||
dir,
|
||||
'example-docs'
|
||||
);
|
||||
|
||||
const localDevelopmentPost =
|
||||
manifestWithLinks.categories[ 0 ].posts[ 0 ];
|
||||
|
||||
expect(
|
||||
localDevelopmentPost.links[ './installation/install-plugin.md' ]
|
||||
).toBeDefined();
|
||||
|
||||
const installationPost =
|
||||
manifestWithLinks.categories[ 0 ].categories[ 0 ].posts[ 0 ];
|
||||
|
||||
expect(
|
||||
localDevelopmentPost.links[ './installation/install-plugin.md' ]
|
||||
).toEqual( installationPost.id );
|
||||
} );
|
||||
} );
|
|
@ -12,13 +12,15 @@ import { Category, Post, generatePostId } from './generate-manifest';
|
|||
/**
|
||||
* Process relative markdown links in the manifest.
|
||||
*
|
||||
* @param manifest Category or Post
|
||||
* @param rootDirectory Root directory of the project
|
||||
* @param projectName Name of the project
|
||||
* @param manifest Category or Post
|
||||
* @param rootDirectory Root directory of the project
|
||||
* @param absoluteSubDir Path to directory of Markdown files to generate the manifest from.
|
||||
* @param projectName Name of the project
|
||||
*/
|
||||
export const processMarkdownLinks = (
|
||||
manifest: Category,
|
||||
rootDirectory: string,
|
||||
absoluteSubDir: string,
|
||||
projectName: string
|
||||
) => {
|
||||
const updatedManifest: Category = { ...manifest };
|
||||
|
@ -36,14 +38,18 @@ export const processMarkdownLinks = (
|
|||
let match;
|
||||
while ( ( match = linkRegex.exec( fileContent ) ) ) {
|
||||
const relativePath = match[ 1 ];
|
||||
const linkedFilePath = path.resolve(
|
||||
const absoluteLinkedFilePath = path.resolve(
|
||||
path.dirname( filePath ),
|
||||
relativePath
|
||||
);
|
||||
const relativeLinkedFilePath = path.relative(
|
||||
absoluteSubDir,
|
||||
absoluteLinkedFilePath
|
||||
);
|
||||
|
||||
if ( fs.existsSync( linkedFilePath ) ) {
|
||||
if ( fs.existsSync( absoluteLinkedFilePath ) ) {
|
||||
const linkedId = generatePostId(
|
||||
linkedFilePath,
|
||||
relativeLinkedFilePath,
|
||||
projectName
|
||||
);
|
||||
updatedPost.links = updatedPost.links || {};
|
||||
|
@ -60,7 +66,12 @@ export const processMarkdownLinks = (
|
|||
if ( updatedManifest.categories ) {
|
||||
updatedManifest.categories = updatedManifest.categories.map(
|
||||
( category ) =>
|
||||
processMarkdownLinks( category, rootDirectory, projectName )
|
||||
processMarkdownLinks(
|
||||
category,
|
||||
rootDirectory,
|
||||
absoluteSubDir,
|
||||
projectName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue