From 09e5945ac68cab2efcb815234bfe09e53e6b0a0d Mon Sep 17 00:00:00 2001 From: ashfame Date: Fri, 27 Dec 2024 09:58:47 +0400 Subject: [PATCH] use TransformersRegistry approach for our own transformations --- src/plugin/class-subjects-controller.php | 29 +++++--- src/plugin/class-transformer.php | 88 +++++++++++------------ src/plugin/class-transformersregistry.php | 4 +- tests/plugin/test-transformer.php | 65 ----------------- 4 files changed, 63 insertions(+), 123 deletions(-) delete mode 100644 tests/plugin/test-transformer.php diff --git a/src/plugin/class-subjects-controller.php b/src/plugin/class-subjects-controller.php index d7a38723..636d9e25 100644 --- a/src/plugin/class-subjects-controller.php +++ b/src/plugin/class-subjects-controller.php @@ -2,8 +2,7 @@ namespace DotOrg\TryWordPress; -use DateTime; -use DateTimeZone; +use Exception; use WP_Error; use WP_REST_Controller; use WP_REST_Response; @@ -290,11 +289,15 @@ public function create_item( $request ): WP_REST_Response|WP_Error { } $subject_type = $this->get_subject_type( $request ); - update_post_meta( $item['ID'], 'subject_type', $subject_type ); + update_post_meta( $item['ID'], 'subject_type', $subject_type->value ); - do_action( 'dl_data_saved', Subject::from_post( $item['ID'] ), 'create' ); + try { + TransformersRegistry::handle( $subject_type, Subject::from_post( $item['ID'] ) ); + } catch ( Exception $e ) { + return new WP_Error( $e->getCode(), $e->getMessage() ); + } - return $this->prepare_item_for_response( $item, $request, $subject_type ); + return $this->prepare_item_for_response( $item, $request ); } public function update_item( $request ): WP_REST_Response|WP_Error { @@ -316,7 +319,13 @@ public function update_item( $request ): WP_REST_Response|WP_Error { update_post_meta( $item['ID'], $key, $value ); } - do_action( 'dl_data_saved', Subject::from_post( $item['ID'] ), 'update' ); + $subject_type = $this->get_subject_type( $request ); + + try { + TransformersRegistry::handle( $subject_type, Subject::from_post( $item['ID'] ) ); + } catch ( Exception $e ) { + return new WP_Error( $e->getCode(), $e->getMessage() ); + } return $this->prepare_item_for_response( $item, $request ); } @@ -385,7 +394,7 @@ public function prepare_item_for_response( $item, $request ): WP_REST_Response|W 'transformedId' => absint( get_post_meta( $item['ID'], Transformer::META_KEY_LIBERATED_OUTPUT, true ) ), ); - foreach ( array_keys( Schema::get()[ $subject_type ]['fields'] ) as $field_name ) { + foreach ( array_keys( Schema::get()[ $subject_type->value ]['fields'] ) as $field_name ) { $response[ 'raw' . ucfirst( $field_name ) ] = get_post_meta( $item['ID'], 'raw_' . $field_name, true ); $response[ 'parsed' . ucfirst( $field_name ) ] = get_post_meta( $item['ID'], 'parsed_' . $field_name, true ); } @@ -409,7 +418,7 @@ public function prepare_item_for_database( $request ): array { $prepared_post['post_author'] = $request_data['authorId'] ?? ''; $prepared_post['meta'] = array(); - foreach ( array_keys( Schema::get()[ $subject_type ]['fields'] ) as $field_name ) { + foreach ( array_keys( Schema::get()[ $subject_type->value ]['fields'] ) as $field_name ) { $prepared_post['meta'][ 'raw_' . $field_name ] = $request_data[ 'raw' . ucfirst( $field_name ) ] ?? ''; $prepared_post['meta'][ 'parsed_' . $field_name ] = $request_data[ 'parsed' . ucfirst( $field_name ) ] ?? ''; } @@ -452,8 +461,8 @@ public function get_post_id_by_guid( string $guid ): ?int { return null; } - private function get_subject_type( $request ): string { + private function get_subject_type( $request ): SubjectType { preg_match( '/\/subjects\/([^\/]+)/', $request->get_route(), $matches ); - return $matches[1]; + return SubjectType::tryFrom( $matches[1] ); } } diff --git a/src/plugin/class-transformer.php b/src/plugin/class-transformer.php index 9e6fcd21..22a8ac80 100644 --- a/src/plugin/class-transformer.php +++ b/src/plugin/class-transformer.php @@ -2,85 +2,81 @@ namespace DotOrg\TryWordPress; -use WP_Post; - class Transformer { public const string META_KEY_LIBERATED_SOURCE = '_data_liberation_source'; public const string META_KEY_LIBERATED_OUTPUT = '_data_liberation_output'; public function __construct() { - add_action( 'dl_data_saved', array( $this, 'transform' ), 10, 2 ); - } - - private function get_post_type_for_transformed_post( int|WP_Post $liberated_post ): string { - if ( is_int( $liberated_post ) ) { - $liberated_post = get_post( $liberated_post ); - } - - $subject_type = get_post_meta( $liberated_post->ID, 'subject_type', true ); - switch ( $subject_type ) { - case 'blog-post': - $post_type = 'post'; - break; - case 'product': - $post_type = 'product'; - break; - case 'page': - $post_type = 'page'; - break; - default: - $post_type = 'post'; - } + TransformersRegistry::add( + SubjectType::BLOGPOST, + array( + 'slug' => 'try_wordpress', + 'description' => 'Try WordPress handling blog-post natively', + ), + array( + $this, + 'handler', + ) + ); - // @TODO: filter name would be changed w.r.t new verb in place of 'transformed' once its decided - return apply_filters( 'post_type_for_transformed_post', $post_type, $liberated_post ); + TransformersRegistry::add( + SubjectType::PAGE, + array( + 'slug' => 'try_wordpress', + 'description' => 'Try WordPress handling page natively', + ), + array( + $this, + 'handler', + ) + ); } - public function transform( Subject $subject, string $verb ): bool { - if ( apply_filters( 'skip_native_transformation', false ) ) { - return true; - } - - $liberated_post_id = $subject->id(); - $liberated_post = get_post( $liberated_post_id ); - - $transformed_post_id = get_post_meta( $liberated_post->ID, self::META_KEY_LIBERATED_OUTPUT, true ); + public function get_post_type( Subject $subject ): string { + return match ( $subject->type ) { + 'page' => 'page', + default => 'post', + }; + } - $title = get_post_meta( $liberated_post->ID, 'parsed_title', true ); + public function handler( Subject $subject ) { + // Since parsed versions come from paste_handler in frontend, look for them in postmeta, instead of subject instance + $title = get_post_meta( $subject->id(), 'parsed_title', true ); if ( empty( $title ) ) { $title = '[Title]'; } - $body = get_post_meta( $liberated_post->ID, 'parsed_content', true ); + $body = get_post_meta( $subject->id(), 'parsed_content', true ); if ( empty( $body ) ) { $body = '[Body]'; } $args = array( - 'post_author' => $liberated_post->post_author, - 'post_date' => get_post_meta( $liberated_post->ID, 'parsed_date', true ), + 'post_author' => $subject->author_id(), + 'post_date' => get_post_meta( $subject->id(), 'parsed_date', true ), 'post_content' => $body, 'post_title' => $title, 'post_status' => 'publish', - 'post_type' => $this->get_post_type_for_transformed_post( $liberated_post->ID ), + 'post_type' => $this->get_post_type( $subject ), ); + + // have we already transformed this subject before? + $transformed_post_id = get_post_meta( $subject->id(), self::META_KEY_LIBERATED_OUTPUT, true ); if ( ! empty( $transformed_post_id ) ) { $args['ID'] = $transformed_post_id; } add_filter( 'wp_insert_post_empty_content', '__return_false' ); - $inserted_post_id = wp_insert_post( $args, true ); + $inserted_post_id = wp_insert_post( $args ); remove_filter( 'wp_insert_post_empty_content', '__return_false' ); // @TODO: handle attachments, terms etc in future // Note: Do not need anything from postmeta. // We should potentially use another plugin here for this purpose and call its API to do it for us. - if ( 0 === $inserted_post_id || is_wp_error( $inserted_post_id ) ) { - return false; + if ( 0 === $inserted_post_id ) { + return null; } - update_post_meta( $inserted_post_id, self::META_KEY_LIBERATED_SOURCE, $liberated_post->ID ); - update_post_meta( $liberated_post->ID, self::META_KEY_LIBERATED_OUTPUT, $inserted_post_id ); - return true; + return $inserted_post_id; } } diff --git a/src/plugin/class-transformersregistry.php b/src/plugin/class-transformersregistry.php index 1ac88f44..e2c22471 100644 --- a/src/plugin/class-transformersregistry.php +++ b/src/plugin/class-transformersregistry.php @@ -33,7 +33,7 @@ public static function add( SubjectType $type, array $identifier, callable $hand self::$handlers[ $type->value ][ $identifier['slug'] ] = array( 'slug' => $identifier['slug'], - 'description' => $identifier['desc'], + 'description' => $identifier['description'], 'handler' => $handler, ); } @@ -85,8 +85,8 @@ public static function handle( SubjectType $type, Subject $subject ): void { $transformed_post_id = $chosen['handler']( $subject ); if ( $transformed_post_id ) { - update_post_meta( $subject->id(), Transformer::META_KEY_LIBERATED_OUTPUT, $transformed_post_id ); update_post_meta( $transformed_post_id, Transformer::META_KEY_LIBERATED_SOURCE, $subject->id() ); + update_post_meta( $subject->id(), Transformer::META_KEY_LIBERATED_OUTPUT, $transformed_post_id ); } } diff --git a/tests/plugin/test-transformer.php b/tests/plugin/test-transformer.php deleted file mode 100644 index 1e04a05c..00000000 --- a/tests/plugin/test-transformer.php +++ /dev/null @@ -1,65 +0,0 @@ -post_id_in_db = wp_insert_post( - array( - 'post_author' => 1, - 'post_date' => '2024-09-12 14:30:00', - 'post_date_gmt' => '2024-09-12 14:30:00', - 'post_content' => 'This is a new post', - 'post_title' => 'Test post', - 'post_status' => 'draft', - 'post_content_filtered' => '

Content 1

Content 2

', - 'guid' => 'https://example.com/x', - 'post_type' => Engine::STORAGE_POST_TYPE, - ) - ); - update_post_meta( $this->post_id_in_db, 'subject_type', 'blog-post' ); - - $this->transformer = new Transformer( 'lib_x' ); - } - - protected function tearDown(): void { - parent::tearDown(); - - $transformed_post_id = get_post_meta( $this->post_id_in_db, Transformer::META_KEY_LIBERATED_OUTPUT, true ); - wp_delete_post( $transformed_post_id, true ); - wp_delete_post( $this->post_id_in_db, true ); - - delete_post_meta( 99, Transformer::META_KEY_LIBERATED_OUTPUT ); - } - - public function testGetPostTypeForTransformedPost() { - $reflection = new ReflectionClass( $this->transformer ); - $method = $reflection->getMethod( 'get_post_type_for_transformed_post' ); - - $result = $method->invokeArgs( $this->transformer, array( $this->post_id_in_db ) ); - $this->assertEquals( 'post', $result ); - - update_post_meta( $this->post_id_in_db, 'subject_type', 'product' ); - - $result = $method->invokeArgs( $this->transformer, array( $this->post_id_in_db ) ); - $this->assertEquals( 'product', $result ); - } - - public function testTransform(): void { - $result = $this->transformer->transform( Subject::from_post( $this->post_id_in_db ), 'whatever' ); // verb isn't currently used - - $transformed_post_id = absint( get_post_meta( $this->post_id_in_db, Transformer::META_KEY_LIBERATED_OUTPUT, true ) ); - - $this->assertEquals( $this->post_id_in_db + 1, $transformed_post_id ); - $this->assertTrue( $result ); - } -}