diff --git a/admin/apple-actions/index/class-push.php b/admin/apple-actions/index/class-push.php index 9bd32964..451c4f7a 100644 --- a/admin/apple-actions/index/class-push.php +++ b/admin/apple-actions/index/class-push.php @@ -78,14 +78,15 @@ public function __construct( $settings, $id ) { * @param boolean $doing_async Optional. Whether the action is being performed asynchronously. * @param int $user_id Optional. The ID of the user performing the action. Defaults to the current user ID. * - * @access public * @return boolean * @throws Action_Exception If the push fails. */ public function perform( $doing_async = false, $user_id = null ) { if ( 'yes' === $this->settings->__get( 'api_async' ) && false === $doing_async ) { + // Do not proceed if this is already pending publish. $pending = get_post_meta( $this->id, 'apple_news_api_pending', true ); + if ( ! empty( $pending ) ) { return false; } @@ -94,9 +95,9 @@ public function perform( $doing_async = false, $user_id = null ) { update_post_meta( $this->id, 'apple_news_api_pending', time() ); wp_schedule_single_event( time(), Admin_Apple_Async::ASYNC_PUSH_HOOK, [ $this->id, get_current_user_id() ] ); - } else { - return $this->push( $user_id ); } + + return $this->push( $user_id ); } /** @@ -213,7 +214,6 @@ private function get(): void { * * @param int $user_id Optional. The ID of the user performing the push. Defaults to current user. * - * @access private * @throws Action_Exception If unable to push. */ private function push( $user_id = null ): void { @@ -438,11 +438,20 @@ private function push( $user_id = null ): void { $this->clean_workspace(); - if ( str_contains( $e->getMessage(), 'WRONG_REVISION' ) ) { - throw new Action_Exception( esc_html__( 'Apple News Error: It seems like the article was updated by another call. If the problem persists, try removing and pushing again.', 'apple-news' ) ); + $original_error_message = $e->getMessage(); + + if ( str_contains( $original_error_message, 'WRONG_REVISION' ) ) { + $error_message = __( 'Apple News Error: It seems like the article was updated by another call. If the problem persists, try removing and pushing again.', 'apple-news' ); + } elseif ( str_contains( $original_error_message, 'NOT_FOUND (keyPath articleId)' ) ) { + // Reset the API postmeta if the article is deleted in Apple News. + $this->delete_post_meta( $this->id ); + + $error_message = __( 'The article seems to be deleted in Apple News. Reindexing the article in Apple News.', 'apple-news' ); } else { - throw new Action_Exception( esc_html__( 'There has been an error with the Apple News API: ', 'apple-news' ) . esc_html( $e->getMessage() ) ); + $error_message = __( 'There has been an error with the Apple News API: ', 'apple-news' ) . esc_html( $original_error_message ); } + + throw new Action_Exception( esc_html( $error_message ) ); } // Print success message. diff --git a/admin/class-admin-apple-post-sync.php b/admin/class-admin-apple-post-sync.php index 9b1b3888..247c789f 100644 --- a/admin/class-admin-apple-post-sync.php +++ b/admin/class-admin-apple-post-sync.php @@ -120,9 +120,9 @@ public function action__transition_post_status( $new_status, $old_status, $post * When a post is published, or a published post updated, trigger this function. * * @since 0.4.0 + * * @param int $id The ID of the post being updated. * @param WP_Post $post The post object being updated. - * @access public */ public function do_publish( $id, $post ) { if ( 'publish' !== $post->post_status @@ -170,6 +170,7 @@ public function do_publish( $id, $post ) { // Proceed with the push. $action = new Apple_Actions\Index\Push( $this->settings, $id ); + try { $action->perform(); } catch ( Apple_Actions\Action_Exception $e ) { diff --git a/tests/admin/apple-actions/index/test-class-push.php b/tests/admin/apple-actions/index/test-class-push.php index cf6593f4..8cf535e2 100644 --- a/tests/admin/apple-actions/index/test-class-push.php +++ b/tests/admin/apple-actions/index/test-class-push.php @@ -305,4 +305,45 @@ public function test_update() { $body = $this->get_body_from_request( $request ); $this->assertEquals( 'Test New Title', $body['title'] ); } + + /** + * Test that the action is able to handle a deleted article. + */ + public function test_update_with_deleted_article(): void { + $article_id = self::factory()->post->create(); + $api_id = 'efabcdef123456'; + + add_post_meta( $article_id, 'apple_news_api_id', $api_id ); + + // Fake the API response for the GET request. + $this->add_http_response( + verb: 'GET', + url: 'https://news-api.apple.com/articles/' . $api_id, + body: wp_json_encode( + [ + 'errors' => [ + [ + 'code' => 'NOT_FOUND', + 'keyPath' => [ 'articleId' ], + 'value' => $api_id, + ], + ], + ] + ), + response: [ + 'code' => 404, + 'message' => 'Not Found', + ] + ); + + $action = new Apple_Actions\Index\Push( $this->settings, $article_id ); + + try { + $action->perform(); + } catch ( Action_Exception $e ) { + $this->assertSame( 'The article seems to be deleted in Apple News. Reindexing the article in Apple News.', $e->getMessage() ); + } + + $this->assertEmpty( get_post_meta( $article_id, 'apple_news_api_id', true ) ); + } }