From ba1d1211ec81cd535ac3097981edee7c4d86bd89 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 11:24:38 +1000 Subject: [PATCH 1/8] Include empty taxonomies when syncing terms. --- includes/utils.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/includes/utils.php b/includes/utils.php index 024490723..8f5549c07 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -438,15 +438,21 @@ function prepare_media( $post_id ) { /** * Format taxonomy terms for consumption * - * @param int $post_id Post ID. * @since 1.0 - * @return array + * + * @param int $post_id Post ID. + * @param array $args Taxonomy query arguments. See get_taxonomies(). + * @return array[] Array of taxonomy terms. */ -function prepare_taxonomy_terms( $post_id ) { +function prepare_taxonomy_terms( $post_id, $args = array() ) { $post = get_post( $post_id ); + if ( empty( $args ) ) { + $args = array( 'publicly_queryable' => true ); + } + $taxonomy_terms = []; - $taxonomies = get_object_taxonomies( $post ); + $taxonomies = get_taxonomies( $args ); /** * Filters the taxonomies that should be synced. From 648332764b7f5ab34fab19b3f0b7917abb274687 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 11:26:06 +1000 Subject: [PATCH 2/8] Only include taxonomies shown in the REST api when updating posts. --- includes/subscriptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/subscriptions.php b/includes/subscriptions.php index fe7fc3ca1..1c79fd50e 100644 --- a/includes/subscriptions.php +++ b/includes/subscriptions.php @@ -273,7 +273,7 @@ function send_notifications( $post ) { 'content' => Utils\get_processed_content( $post->post_content ), 'excerpt' => $post->post_excerpt, 'distributor_media' => \Distributor\Utils\prepare_media( $post_id ), - 'distributor_terms' => \Distributor\Utils\prepare_taxonomy_terms( $post_id ), + 'distributor_terms' => \Distributor\Utils\prepare_taxonomy_terms( $post_id, array( 'show_in_rest' => true ) ), 'distributor_meta' => \Distributor\Utils\prepare_meta( $post_id ), ], ]; From 0e6ef2858fcc74b79407197306b739e130923989 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 11:31:29 +1000 Subject: [PATCH 3/8] Send subscription updates as JSON data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows updates which include an empting of a taxonomy of all it’s terms. Sending a taxonomy with an empty array as standard post data gets removed from the REST request. --- includes/subscriptions.php | 59 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/includes/subscriptions.php b/includes/subscriptions.php index 1c79fd50e..2fd92df1d 100644 --- a/includes/subscriptions.php +++ b/includes/subscriptions.php @@ -284,33 +284,42 @@ function send_notifications( $post ) { } } + /** + * Filter the timeout used when calling `\Distributor\Subscriptions\send_notifications` + * + * @hook dt_subscription_post_timeout + * + * @param {int} $timeout The timeout to use for the remote post. Default `5`. + * @param {WP_Post} $post The post object + * + * @return {int} The timeout to use for the remote post. + */ + $request_timeout = apply_filters( 'dt_subscription_post_timeout', 5, $post ); + + /** + * Filter the arguments sent to the remote server during a subscription update. + * + * @since 1.3.0 + * @hook dt_subscription_post_args + * + * @param {array} $post_body The request body to send. + * @param {WP_Post} $post The WP_Post that is being pushed. + * + * @return {array} The request body to send. + */ + $post_body = apply_filters( 'dt_subscription_post_args', $post_body, $post ); + + $post_arguments = [ + 'timeout' => $request_timeout, + 'body' => wp_json_encode( $post_body ), + 'headers' => [ + 'Content-Type' => 'application/json', + ], + ]; + $request = wp_remote_post( untrailingslashit( $target_url ) . '/wp/v2/dt_subscription/receive', - [ - /** - * Filter the timeout used when calling `\Distributor\Subscriptions\send_notifications` - * - * @hook dt_subscription_post_timeout - * - * @param {int} $timeout The timeout to use for the remote post. Default `5`. - * @param {WP_Post} $post The post object - * - * @return {int} The timeout to use for the remote post. - */ - 'timeout' => apply_filters( 'dt_subscription_post_timeout', 5, $post ), - /** - * Filter the arguments sent to the remote server during a subscription update. - * - * @since 1.3.0 - * @hook dt_subscription_post_args - * - * @param {array} $post_body The request body to send. - * @param {WP_Post} $post The WP_Post that is being pushed. - * - * @return {array} The request body to send. - */ - 'body' => apply_filters( 'dt_subscription_post_args', $post_body, $post ), - ] + $post_arguments ); if ( ! is_wp_error( $request ) ) { From 3b9316dd8add31c5da3b232063abfeddf9dc1fe6 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 11:31:55 +1000 Subject: [PATCH 4/8] Only permit taxonomy updates for those that are shown in the REST API. --- includes/classes/API/SubscriptionsController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/classes/API/SubscriptionsController.php b/includes/classes/API/SubscriptionsController.php index 766f9f45e..15cc484ee 100644 --- a/includes/classes/API/SubscriptionsController.php +++ b/includes/classes/API/SubscriptionsController.php @@ -248,6 +248,11 @@ public function receive_item( $request ) { 'media' => ( isset( $request['post_data']['distributor_media'] ) ) ? $request['post_data']['distributor_media'] : [], ]; + // Limit taxonomy updates to those shown in the REST API. + $rest_taxonomies = get_taxonomies( [ 'show_in_rest' => true ] ); + $rest_taxonomies = array_fill_keys( $rest_taxonomies, true ); + $update['terms'] = array_intersect_key( $update['terms'], $rest_taxonomies ); + update_post_meta( (int) $request['post_id'], 'dt_subscription_update', $update ); $unlinked = (bool) get_post_meta( $request['post_id'], 'dt_unlinked', true ); From a89d002b2f3606c7231fce34bd7a4678404282ef Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 12:02:55 +1000 Subject: [PATCH 5/8] Mock wp_json_encode() for test suite. --- tests/php/includes/common.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/php/includes/common.php b/tests/php/includes/common.php index 17e9b58cb..1fc4b1b0d 100644 --- a/tests/php/includes/common.php +++ b/tests/php/includes/common.php @@ -249,6 +249,20 @@ function get_allowed_mime_types() { ]; } +/** + * Mock wp_json_encode() function. + * + * @since x.x.x + * + * @param mixed $data Data to encode. + * @param int $options Optional. Options to be passed to json_encode(). Default 0. + * @param int $depth Optional. Maximum depth to walk through $data. + * @return string|false The JSON encoded string, or false if it cannot be encoded. + */ +function wp_json_encode( $data, $options = 0, $depth = 512 ) { + return json_encode( $data, $options, $depth ); +} + /** * Stub for remove_filter to avoid failure in test_remote_get() * From 3b8ed5c717f52f65cde1e091d011b8c3dd0d47b8 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 30 Sep 2022 14:30:21 +1000 Subject: [PATCH 6/8] Expect JSON encoded data. --- tests/php/SubscriptionsTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/php/SubscriptionsTest.php b/tests/php/SubscriptionsTest.php index 0453d57b8..d82ee8f03 100644 --- a/tests/php/SubscriptionsTest.php +++ b/tests/php/SubscriptionsTest.php @@ -547,7 +547,7 @@ public function test_send_notifications_remote_post_exists() { $target_url . '/wp/v2/dt_subscription/receive', [ 'timeout' => 5, - 'body' => [ + 'body' => wp_json_encode( [ 'post_id' => $remote_post_id, 'signature' => $signature, 'post_data' => [ @@ -560,7 +560,10 @@ public function test_send_notifications_remote_post_exists() { 'distributor_terms' => [], 'distributor_meta' => [], ], - ], + ] ), + 'headers' => [ + 'Content-Type' => 'application/json', + ] ], ], ] From 9156b1aeb6a63d5639e129d9d5d0f764fd49c1d6 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:02:18 +1100 Subject: [PATCH 7/8] Fix tests: JSON encoded data is strict about order. --- tests/php/SubscriptionsTest.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/php/SubscriptionsTest.php b/tests/php/SubscriptionsTest.php index d82ee8f03..ecf303518 100644 --- a/tests/php/SubscriptionsTest.php +++ b/tests/php/SubscriptionsTest.php @@ -359,19 +359,22 @@ public function test_send_notifications_no_remote_post() { $target_url . '/wp/v2/dt_subscription/receive', [ 'timeout' => 5, - 'body' => [ + 'body' => wp_json_encode( [ 'post_id' => $remote_post_id, 'signature' => $signature, 'post_data' => [ 'title' => 'title', + 'slug' => 'slug', + 'post_type' => 'post', 'content' => 'content', 'excerpt' => 'excerpt', - 'post_type' => 'post', - 'slug' => 'slug', 'distributor_media' => [], 'distributor_terms' => [], 'distributor_meta' => [], - ], + ] + ] ), + 'headers' => [ + 'Content-Type' => 'application/json', ], ], ], @@ -553,9 +556,9 @@ public function test_send_notifications_remote_post_exists() { 'post_data' => [ 'title' => 'title', 'slug' => 'slug', + 'post_type' => 'post', 'content' => 'content', 'excerpt' => 'excerpt', - 'post_type' => 'post', 'distributor_media' => [], 'distributor_terms' => [], 'distributor_meta' => [], From a8bbdcdd8edd11aa9e98c22a0f0bfdd55d7b7851 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:04:11 +1100 Subject: [PATCH 8/8] Fix tests: Account for wp_mock error. Account for https://github.com/10up/wp_mock/issues/173 --- tests/php/SubscriptionsTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/php/SubscriptionsTest.php b/tests/php/SubscriptionsTest.php index ecf303518..e46f25e37 100644 --- a/tests/php/SubscriptionsTest.php +++ b/tests/php/SubscriptionsTest.php @@ -368,9 +368,9 @@ public function test_send_notifications_no_remote_post() { 'post_type' => 'post', 'content' => 'content', 'excerpt' => 'excerpt', - 'distributor_media' => [], - 'distributor_terms' => [], - 'distributor_meta' => [], + 'distributor_media' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 + 'distributor_terms' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 + 'distributor_meta' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 ] ] ), 'headers' => [ @@ -559,9 +559,9 @@ public function test_send_notifications_remote_post_exists() { 'post_type' => 'post', 'content' => 'content', 'excerpt' => 'excerpt', - 'distributor_media' => [], - 'distributor_terms' => [], - 'distributor_meta' => [], + 'distributor_media' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 + 'distributor_terms' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 + 'distributor_meta' => null, // Accounts for https://github.com/10up/wp_mock/issues/173 ], ] ), 'headers' => [