From 84c3f03657de0e4b288c4f7e4a78be89a276117d Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Mon, 20 Feb 2023 14:12:17 +1100
Subject: [PATCH 01/57] Use post abstraction for pulling network posts.
---
.../NetworkSiteConnection.php | 77 +++++++++----------
1 file changed, 37 insertions(+), 40 deletions(-)
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index abebb768e..47ac1935f 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -256,14 +256,24 @@ public function pull( $items ) {
$created_posts = array();
foreach ( $items as $item_array ) {
- $post = $this->remote_get( [ 'id' => $item_array['remote_post_id'] ] );
+ $update = false;
+ $insert_args = array();
+ if ( ! empty( $item_array['post_status'] ) ) {
+ $insert_args['post_status'] = $item_array['post_status'];
+ }
+ if ( ! empty( $item_array['post_id'] ) ) {
+ $insert_args['remote_post_id'] = $item_array['post_id'];
+ $update = true;
+ }
+
+ $post = $this->remote_get( [ 'id' => $item_array['remote_post_id'] ], $insert_args );
if ( is_wp_error( $post ) ) {
$created_posts[] = $post;
continue;
}
- $post_props = get_object_vars( $post );
+ $post_props = $post;
$post_array = array();
$current_blog_id = get_current_blog_id();
@@ -278,41 +288,20 @@ public function pull( $items ) {
}
}
- foreach ( $post_props as $key => $value ) {
- $post_array[ $key ] = $value;
- }
-
- if ( ! empty( $item_array['post_id'] ) ) {
- $post_array['ID'] = $item_array['post_id'];
- } else {
- unset( $post_array['ID'] );
- }
-
- if ( isset( $post_array['post_parent'] ) ) {
- unset( $post_array['post_parent'] );
- }
-
- if ( ! empty( $item_array['post_status'] ) ) {
- $post_array['post_status'] = $item_array['post_status'];
- }
-
add_filter( 'wp_insert_post_data', array( '\Distributor\InternalConnections\NetworkSiteConnection', 'maybe_set_modified_date' ), 10, 2 );
// Filter documented in includes/classes/ExternalConnections/WordPressExternalConnection.php
$new_post_args = Utils\post_args_allow_list( apply_filters( 'dt_pull_post_args', $post_array, $item_array['remote_post_id'], $post, $this ) );
- $new_post_id = wp_insert_post( wp_slash( $new_post_args ) );
-
+ if ( $update ) {
+ $new_post_id = wp_update_post( wp_slash( $new_post_args ) );
+ } else {
+ $new_post_id = wp_insert_post( wp_slash( $new_post_args ) );
+ }
remove_filter( 'wp_insert_post_data', array( '\Distributor\InternalConnections\NetworkSiteConnection', 'maybe_set_modified_date' ), 10, 2 );
if ( ! is_wp_error( $new_post_id ) ) {
- update_post_meta( $new_post_id, 'dt_original_post_id', (int) $item_array['remote_post_id'] );
update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $this->site->blog_id );
update_post_meta( $new_post_id, 'dt_syndicate_time', time() );
- update_post_meta( $new_post_id, 'dt_original_post_url', esc_url_raw( $post->link ) );
-
- if ( ! empty( $post->post_parent ) ) {
- update_post_meta( $new_post_id, 'dt_original_post_parent', (int) $post->post_parent );
- }
/**
* Allow bypassing of all meta processing.
@@ -321,15 +310,15 @@ public function pull( $items ) {
*
* @param {bool} true If Distributor should set the post meta.
* @param {int} $new_post_id The newly created post ID.
- * @param {array} $post->meta List of meta items attached to the post, formatted by {@link \Distributor\Utils\prepare_meta()}.
+ * @param {array} $post_meta List of meta items attached to the post, formatted by {@link \Distributor\Utils\prepare_meta()}.
* @param {int} $remote_post_id The original post ID.
* @param {array} $post_array The arguments passed into wp_insert_post.
* @param {NetworkSiteConnection} $this The Distributor connection being pulled from.
*
* @return {bool} If Distributor should set the post meta.
*/
- if ( apply_filters( 'dt_pull_post_meta', true, $new_post_id, $post->meta, $item_array['remote_post_id'], $post_array, $this ) ) {
- \Distributor\Utils\set_meta( $new_post_id, $post->meta );
+ if ( apply_filters( 'dt_pull_post_meta', true, $new_post_id, $post['meta'], $item_array['remote_post_id'], $post_array, $this ) ) {
+ \Distributor\Utils\set_meta( $new_post_id, $post['meta'] );
}
/**
@@ -339,15 +328,15 @@ public function pull( $items ) {
*
* @param {bool} true If Distributor should set the post terms.
* @param {int} $new_post_id The newly created post ID.
- * @param {array} $post->terms List of terms items attached to the post, formatted by {@link \Distributor\Utils\prepare_taxonomy_terms()}.
+ * @param {array} $post_terms List of terms items attached to the post, formatted by {@link \Distributor\Utils\prepare_taxonomy_terms()}.
* @param {int} $remote_post_id The original post ID.
* @param {array} $post_array The arguments passed into wp_insert_post.
* @param {NetworkSiteConnection} $this The Distributor connection being pulled from.
*
* @return {bool} If Distributor should set the post terms.
*/
- if ( apply_filters( 'dt_pull_post_terms', true, $new_post_id, $post->terms, $item_array['remote_post_id'], $post_array, $this ) ) {
- \Distributor\Utils\set_taxonomy_terms( $new_post_id, $post->terms );
+ if ( apply_filters( 'dt_pull_post_terms', true, $new_post_id, $post['terms'], $item_array['remote_post_id'], $post_array, $this ) ) {
+ \Distributor\Utils\set_taxonomy_terms( $new_post_id, $post['terms'] );
}
/**
@@ -357,15 +346,15 @@ public function pull( $items ) {
*
* @param {bool} true If Distributor should set the post media.
* @param {int} $new_post_id The newly created post ID.
- * @param {array} $post->media List of media items attached to the post, formatted by {@link \Distributor\Utils\prepare_media()}.
+ * @param {array} $post_media List of media items attached to the post, formatted by {@link \Distributor\Utils\prepare_media()}.
* @param {int} $remote_post_id The original post ID.
* @param {array} $post_array The arguments passed into wp_insert_post.
* @param {NetworkSiteConnection} $this The Distributor connection being pulled from.
*
* @return {bool} If Distributor should set the post media.
*/
- if ( apply_filters( 'dt_pull_post_media', true, $new_post_id, $post->media, $item_array['remote_post_id'], $post_array, $this ) ) {
- \Distributor\Utils\set_media( $new_post_id, $post->media, [ 'use_filesystem' => true ] );
+ if ( apply_filters( 'dt_pull_post_media', true, $new_post_id, $post['media'], $item_array['remote_post_id'], $post_array, $this ) ) {
+ \Distributor\Utils\set_media( $new_post_id, $post['media'], [ 'use_filesystem' => true ] );
};
}
@@ -504,11 +493,18 @@ public function get_post_types() {
/**
* Remotely get posts so we can list them for pulling
*
- * @param array $args Array of args for getting.
* @since 0.8
+ * @since 2.0.0 Added $new_post_args parameter.
+ *
+ * @param array $args Array of args for getting.
+ * @param array $new_post_args {
+ * Array of args for creating new post.
+ *
+ * @type string $post_status Post status for new post.
+ * }
* @return array|WP_Post|bool
*/
- public function remote_get( $args = array() ) {
+ public function remote_get( $args = array(), $new_post_args = array() ) {
$id = ( empty( $args['id'] ) ) ? false : $args['id'];
@@ -593,7 +589,8 @@ public function remote_get( $args = array() ) {
if ( empty( $post ) ) {
$formatted_post = false;
} else {
- $formatted_post = Utils\prepare_post( $post );
+ $dt_post = new DistributorPost( $post );
+ $formatted_post = $dt_post->to_insert( $new_post_args );
}
restore_current_blog();
From 77080f6f06bc80e84add68fc7e3058c170d6374c Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Mon, 27 Feb 2023 13:32:26 +1100
Subject: [PATCH 02/57] Rename get_pull_content to get_pull_content_list.
---
includes/rest-api.php | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index c5d40f3c8..a1de4b4ee 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -149,7 +149,7 @@ function register_rest_routes() {
'distributor/list-pull-content',
array(
'methods' => 'POST',
- 'callback' => __NAMESPACE__ . '\get_pull_content',
+ 'callback' => __NAMESPACE__ . '\get_pull_content_list',
'permission_callback' => __NAMESPACE__ . '\\get_pull_content_permissions',
'args' => get_pull_content_list_args(),
)
@@ -433,10 +433,12 @@ function check_post_types_permissions() {
/**
* Get a list of content to show on the Pull screen
*
+ * @since x.x.x Renamed from get_pull_content() to get_pull_content_list().
+ *
* @param \WP_Rest_Request $request API request arguments
* @return \WP_REST_Response|\WP_Error
*/
-function get_pull_content( $request ) {
+function get_pull_content_list( $request ) {
$args = [
'posts_per_page' => isset( $request['posts_per_page'] ) ? $request['posts_per_page'] : 20,
'paged' => isset( $request['page'] ) ? $request['page'] : 1,
@@ -519,6 +521,19 @@ function get_pull_content( $request ) {
return $response;
}
+/**
+ * Get a list of content to show on the Pull screen
+ *
+ * @since x.x.x Deprecated in favour of get_pull_content_list().
+ *
+ * @param array ...$args Arguments.
+ * @return \WP_REST_Response|\WP_Error
+ */
+function get_pull_content( ...$args ) {
+ _deprecated_function( __FUNCTION__, 'x.x.x', __NAMESPACE__ . '\\get_pull_content_list' );
+ return get_pull_content_list( ...$args );
+}
+
/**
* Checks if a post can be read.
*
From 7ab2daddab675bce409dc86e547724b0eb63bd46 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 15 Mar 2023 15:29:00 +1100
Subject: [PATCH 03/57] Expose Distributor version in REST headers.
---
includes/bootstrap.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/includes/bootstrap.php b/includes/bootstrap.php
index 1accb41a2..43cab6c6f 100644
--- a/includes/bootstrap.php
+++ b/includes/bootstrap.php
@@ -54,6 +54,7 @@ function() {
'rest_post_dispatch',
function( $response ) {
$response->header( 'X-Distributor', 'yes' );
+ $response->header( 'X-Distributor-Version', DT_VERSION );
return $response;
}
From af11b17c6d0dff77d391edcd9cc70a9d8b7ad217 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 15 Mar 2023 15:58:51 +1100
Subject: [PATCH 04/57] Include X-Distributor-Version header in requests.
---
includes/classes/Authentication.php | 10 ++++++++++
includes/subscriptions.php | 6 +++++-
includes/utils.php | 3 +++
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/includes/classes/Authentication.php b/includes/classes/Authentication.php
index ec7043455..315ea0302 100644
--- a/includes/classes/Authentication.php
+++ b/includes/classes/Authentication.php
@@ -47,6 +47,11 @@ public function __construct( $args ) {
* @return array
*/
public function format_get_args( $args = array(), $context = array() ) {
+ if ( ! isset( $args['headers'] ) ) {
+ $args['headers'] = array();
+ }
+ $args['headers']['X-Distributor-Version'] = DT_VERSION;
+
/**
* Format request args for a GET request so auth occurs.
*
@@ -71,6 +76,11 @@ public function format_get_args( $args = array(), $context = array() ) {
* @return array
*/
public function format_post_args( $args, $context = array() ) {
+ if ( ! isset( $args['headers'] ) ) {
+ $args['headers'] = array();
+ }
+ $args['headers']['X-Distributor-Version'] = DT_VERSION;
+
/**
* Format request args for a POST request so auth occurs
*
diff --git a/includes/subscriptions.php b/includes/subscriptions.php
index 2fd92df1d..242c2109f 100644
--- a/includes/subscriptions.php
+++ b/includes/subscriptions.php
@@ -219,6 +219,9 @@ function delete_subscriptions( $post_id ) {
// phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
'timeout' => 5,
'blocking' => \Distributor\Utils\is_dt_debug(),
+ 'headers' => array(
+ 'X-Distributor-Version' => DT_VERSION,
+ ),
'body' => [
'post_id' => $remote_post_id,
'signature' => $signature,
@@ -313,7 +316,8 @@ function send_notifications( $post ) {
'timeout' => $request_timeout,
'body' => wp_json_encode( $post_body ),
'headers' => [
- 'Content-Type' => 'application/json',
+ 'Content-Type' => 'application/json',
+ 'X-Distributor-Version' => DT_VERSION,
],
];
diff --git a/includes/utils.php b/includes/utils.php
index 587190986..f7158d25a 100644
--- a/includes/utils.php
+++ b/includes/utils.php
@@ -108,6 +108,9 @@ function check_license_key( $email, $license_key ) {
[
// phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
'timeout' => 10,
+ 'headers' => [
+ 'X-Distributor-Version' => DT_VERSION,
+ ],
'body' => [
'license_key' => $license_key,
'email' => $email,
From 4db47804e9014f1f56f8321d085482cb3183006b Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 16 Mar 2023 12:13:45 +1100
Subject: [PATCH 05/57] Introduce helper function to determine if running a
development version of the plugin.
---
includes/settings.php | 2 +-
includes/utils.php | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/includes/settings.php b/includes/settings.php
index fcf544acb..3cf6705a6 100644
--- a/includes/settings.php
+++ b/includes/settings.php
@@ -126,7 +126,7 @@ function update_notice( $plugin_file, $plugin_data, $status ) {
*/
function maybe_notice() {
if ( 0 === strpos( get_current_screen()->parent_base, 'distributor' ) ) {
- if ( file_exists( DT_PLUGIN_PATH . 'composer.lock' ) ) {
+ if ( Utils\is_development_version() ) {
?>
diff --git a/includes/utils.php b/includes/utils.php
index f7158d25a..d51dc05a3 100644
--- a/includes/utils.php
+++ b/includes/utils.php
@@ -9,6 +9,17 @@
use Distributor\DistributorPost;
+/**
+ * Determine if this is a development install of Distributor.
+ *
+ * @since x.x.x
+ *
+ * @return bool True if this is a development install, false otherwise.
+ */
+function is_development_version() {
+ return file_exists( DT_PLUGIN_PATH . 'composer.lock' );
+}
+
/**
* Determine if we are on VIP
*
From df37d7786e2176d7c801a190de744571b902cca3 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 16 Mar 2023 13:29:36 +1100
Subject: [PATCH 06/57] Ensure compatible version of Distributor is used.
---
includes/rest-api.php | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index a1de4b4ee..221c9665f 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -223,6 +223,32 @@ function get_pull_content_list_args() {
* @return bool Whether the current user has permission to pull content.
*/
function get_pull_content_permissions( $request ) {
+ /*
+ * Ensure Distributor requests are coming from a supported version.
+ *
+ * Changes to this endpoint in Distributor 2.0.0 require both the source and remote
+ * sites use a 2.x release of Distributor. This check ensures that the remote site
+ * is running a version of Distributor that supports the new endpoint.
+ *
+ * Development versions of the plugin and Non-Distributor requests are allowed
+ * to pass through this check.
+ */
+ if (
+ true !== Utils\is_development_version()
+ && null !== $request->get_param( 'distributor_request' )
+ && (
+ null === $request->get_header( 'X-Distributor-Version' )
+ || version_compare( $request->get_header( 'X-Distributor-Version' ), '2.0.0', '<' )
+ )
+ ) {
+ return new \WP_Error(
+ 'distributor_pull_content_permissions',
+ esc_html__( 'Pulling content from external connections requires Distributor version 2.0.0 or later.', 'distributor' ),
+ array( 'status' => 403 )
+ );
+
+ }
+
$post_type = $request->get_param( 'post_type' );
if ( ! $post_type ) {
return false;
From a844ea35c2257e9dec9c6edcb91474bc5c2b8380 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 16 Mar 2023 14:53:57 +1100
Subject: [PATCH 07/57] Use post abstraction in pull list endpoint.
---
includes/rest-api.php | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 221c9665f..464d0998a 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -7,6 +7,7 @@
namespace Distributor\RestApi;
+use Distributor\DistributorPost;
use Distributor\Utils;
/**
@@ -521,22 +522,8 @@ function get_pull_content_list( $request ) {
continue;
}
- $formatted_posts[] = array(
- 'id' => $post->ID,
- 'title' => array( 'rendered' => $post->post_title ),
- 'excerpt' => array( 'rendered' => $post->post_excerpt ),
- 'content' => array( 'raw' => $post->post_content ),
- 'password' => $post->post_password,
- 'date' => $post->post_date,
- 'date_gmt' => $post->post_date_gmt,
- 'guid' => array( 'rendered' => $post->guid ),
- 'modified' => $post->post_modified,
- 'modified_gmt' => $post->post_modified_gmt,
- 'type' => $post->post_type,
- 'link' => get_the_permalink( $post ),
- 'comment_status' => $post->comment_status,
- 'ping_status' => $post->ping_status,
- );
+ $dt_post = new DistributorPost( $post->ID );
+ $formatted_posts[] = $dt_post->to_insert();
}
$response = rest_ensure_response( $formatted_posts );
From 12c28319be713cb40793dd6b2798a1eaf04511d2 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 17 Mar 2023 11:30:34 +1100
Subject: [PATCH 08/57] Add method to include additional data required for
external pull screens.
---
includes/classes/DistributorPost.php | 31 ++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/includes/classes/DistributorPost.php b/includes/classes/DistributorPost.php
index e1e1400d3..c210b1cd6 100644
--- a/includes/classes/DistributorPost.php
+++ b/includes/classes/DistributorPost.php
@@ -44,6 +44,7 @@
* @method array get_media()
* @method array post_data()
* @method array to_insert( array $args = [] )
+ * @method array to_pull_list( array $args = [] )
* @method array to_rest( array $args = [] )
*/
class DistributorPost {
@@ -816,6 +817,36 @@ protected function to_insert( $args = array() ) {
return $insert;
}
+ /**
+ * Get the post data in a format suitable for the pull screen.
+ *
+ * This is a wrapper for the ::to_insert() method that includes extra
+ * data required for the pull screen.
+ *
+ * @param mixed $args {
+ * Optional. Array of push arguments
+ * @see ::to_insert() for arguments.
+ * }
+ * @return array Post data formatted for the pull screen.
+ */
+ protected function to_pull_list( $args = array() ) {
+ $display_data = $this->to_insert( $args );
+
+ // Additional information required for pull screen.
+ $display_data['ID'] = $this->post->ID;
+ $display_data['date'] = $this->post->post_date;
+ $display_data['date_gmt'] = $this->post->post_date_gmt;
+ $display_data['modified'] = $this->post->post_modified;
+ $display_data['modified_gmt'] = $this->post->post_modified_gmt;
+ $display_data['post_password'] = $this->post->post_password;
+ $display_data['guid'] = $this->post->guid;
+ $display_data['comment_status'] = $this->post->comment_status;
+ $display_data['ping_status'] = $this->post->ping_status;
+ $display_data['link'] = $this->get_permalink();
+
+ return $display_data;
+ }
+
/**
* Get the post data in a format suitable for the distributor REST API endpoint.
*
From 70a894cc336116c3d5dc8c177d58e305b332e818 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 17 Mar 2023 11:30:58 +1100
Subject: [PATCH 09/57] Use new method for pull screen lists.
---
includes/rest-api.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 464d0998a..bce84fc07 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -523,7 +523,7 @@ function get_pull_content_list( $request ) {
}
$dt_post = new DistributorPost( $post->ID );
- $formatted_posts[] = $dt_post->to_insert();
+ $formatted_posts[] = $dt_post->to_pull_list();
}
$response = rest_ensure_response( $formatted_posts );
From f0f76777f5510f7dc531620edbba51ad80aa39e3 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 13:55:45 +1100
Subject: [PATCH 10/57] Accept arrays of post types and statuses.
---
includes/rest-api.php | 141 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 127 insertions(+), 14 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index bce84fc07..ca3a279d1 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -9,6 +9,7 @@
use Distributor\DistributorPost;
use Distributor\Utils;
+use WP_Error;
/**
* Setup actions and filters
@@ -191,9 +192,71 @@ function get_pull_content_list_args() {
),
'post_type' => array(
'description' => esc_html__( 'Limit results to content matching a certain type.', 'distributor' ),
- 'type' => 'string',
- 'default' => 'post',
- 'sanitize_callback' => 'sanitize_text_field',
+ 'type' => array( 'array', 'string' ),
+ 'items' => array(
+ 'type' => 'string',
+ ),
+ 'default' => array( 'post' ),
+ 'validate_callback' => function( $param ) {
+ if ( is_string( $param ) ) {
+ return sanitize_key( $param ) === $param;
+ }
+
+ foreach ( $param as $post_type ) {
+ if ( sanitize_key( $post_type ) !== $post_type ) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+ 'sanitize_callback' => function( $param ) {
+ if ( is_string( $param ) ) {
+ $param = array( $param );
+ }
+
+ $allowed_post_types = array_keys(
+ get_post_types(
+ array(
+ 'show_in_rest' => true,
+ )
+ )
+ );
+
+ /*
+ * Only post types viewable on the front end should be allowed.
+ *
+ * Some post types may be visible in the REST API but not intended
+ * to be viewed on the front end. This removes any such posts from the
+ * list of allowed post types.
+ *
+ * `is_post_type_viewable()` is used to filter the results as
+ * WordPress applies different rules for custom and built in post
+ * types to determine whether they are viewable on the front end.
+ */
+ $allowed_post_types = array_filter( $allowed_post_types, 'is_post_type_viewable' );
+
+ if ( in_array( 'any', $param, true ) ) {
+ $param = $allowed_post_types;
+ } else {
+ $param = array_intersect( $param, $allowed_post_types );
+ }
+
+ $param = array_filter(
+ $param,
+ function( $post_type ) {
+ $post_type_object = get_post_type_object( $post_type );
+ return current_user_can( $post_type_object->cap->edit_posts );
+ }
+ );
+
+ if ( empty( $param ) ) {
+ // This will cause the parameter to fall back to the default.
+ $param = null;
+ }
+
+ return $param;
+ },
'validate_callback' => 'rest_validate_request_arg',
),
'search' => array(
@@ -201,14 +264,53 @@ function get_pull_content_list_args() {
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
),
- 'post_status' => array(
- 'default' => 'publish',
- 'description' => esc_html__( 'Limit result set to content assigned one or more statuses.', 'distributor' ),
- 'type' => 'array',
- 'items' => array(
- 'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ),
+ 'post_status' => array(
+ 'default' => array( 'publish' ),
+ 'description' => esc_html__( 'Limit result set to content assigned one or more statuses.', 'distributor' ),
+ 'type' => array( 'array', 'string' ),
+ 'items' => array(
'type' => 'string',
),
+ 'validate_callback' => function( $param ) {
+ if ( is_string( $param ) ) {
+ return sanitize_key( $param ) === $param;
+ }
+
+ foreach ( $param as $post_status ) {
+ if ( sanitize_key( $post_status ) !== $post_status ) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+ 'sanitize_callback' => function( $param ) {
+ if ( is_string( $param ) ) {
+ $param = array( $param );
+ }
+
+ /*
+ * Only show post statuses viewable post statues.
+ *
+ * `is_post_type_viewable()` is used to filter the results as
+ * WordPress applies a complex set of rules to determine if a post
+ * status is viewable.
+ */
+ $allowed_statues = array_keys( array_filter( get_post_stati(), 'is_post_type_viewable' ) );
+
+ if ( in_array( 'any', $param, true ) ) {
+ return $allowed_statues;
+ }
+
+ $param = array_intersect( $param, $allowed_statues );
+
+ if ( empty( $param ) ) {
+ // This will cause the parameter to fall back to the default.
+ $param = null;
+ }
+
+ return $param;
+ },
),
);
}
@@ -251,16 +353,27 @@ function get_pull_content_permissions( $request ) {
}
$post_type = $request->get_param( 'post_type' );
- if ( ! $post_type ) {
+ if ( empty( $post_type ) ) {
return false;
}
- $post_type_object = get_post_type_object( $post_type );
- if ( ! $post_type_object ) {
- return false;
+ if ( is_string( $post_type ) ) {
+ $post_type = array( $post_type );
+ }
+
+ foreach ( $post_type as $single_post_type ) {
+ $post_type_object = get_post_type_object( $single_post_type );
+ if ( ! $post_type_object ) {
+ return false;
+ }
+
+ if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {
+ return false;
+ }
}
- return current_user_can( $post_type_object->cap->edit_posts );
+ // User can edit all post types.
+ return true;
}
/**
From a66607d4c0953fba0c2e3735765ada66c1c5e9ae Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 13:59:38 +1100
Subject: [PATCH 11/57] Introduce include parameter.
---
includes/rest-api.php | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index ca3a279d1..7e0477d7d 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -174,6 +174,21 @@ function get_pull_content_list_args() {
),
'default' => array(),
),
+ 'include' => array(
+ 'description' => esc_html__( 'Ensure result set includes specific IDs.', 'distributor' ),
+ 'type' => array( 'array', 'integer' ),
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ 'default' => array(),
+ 'sanitize_callback' => function( $param ) {
+ if ( ! is_array( $param ) ) {
+ $param = array( $param );
+ }
+
+ return wp_parse_id_list( $param );
+ },
+ ),
'page' => array(
'description' => esc_html__( 'Current page of the collection.', 'distributor' ),
'type' => 'integer',
@@ -594,6 +609,10 @@ function get_pull_content_list( $request ) {
$args['post__not_in'] = $request['exclude'];
}
+ if ( ! empty( $request['include'] ) ) {
+ $args['post__in'] = $request['include'];
+ }
+
/**
* Filters WP_Query arguments when querying posts via the REST API.
*
From ba34f34163a98024aa00436e1530c61c4618012e Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 14:29:15 +1100
Subject: [PATCH 12/57] Add original site details to pull formatted content.
---
includes/classes/DistributorPost.php | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/includes/classes/DistributorPost.php b/includes/classes/DistributorPost.php
index c210b1cd6..4766c6e6e 100644
--- a/includes/classes/DistributorPost.php
+++ b/includes/classes/DistributorPost.php
@@ -833,16 +833,18 @@ protected function to_pull_list( $args = array() ) {
$display_data = $this->to_insert( $args );
// Additional information required for pull screen.
- $display_data['ID'] = $this->post->ID;
- $display_data['date'] = $this->post->post_date;
- $display_data['date_gmt'] = $this->post->post_date_gmt;
- $display_data['modified'] = $this->post->post_modified;
- $display_data['modified_gmt'] = $this->post->post_modified_gmt;
- $display_data['post_password'] = $this->post->post_password;
- $display_data['guid'] = $this->post->guid;
- $display_data['comment_status'] = $this->post->comment_status;
- $display_data['ping_status'] = $this->post->ping_status;
- $display_data['link'] = $this->get_permalink();
+ $display_data['ID'] = $this->post->ID;
+ $display_data['date'] = $this->post->post_date;
+ $display_data['date_gmt'] = $this->post->post_date_gmt;
+ $display_data['modified'] = $this->post->post_modified;
+ $display_data['modified_gmt'] = $this->post->post_modified_gmt;
+ $display_data['post_password'] = $this->post->post_password;
+ $display_data['guid'] = $this->post->guid;
+ $display_data['comment_status'] = $this->post->comment_status;
+ $display_data['ping_status'] = $this->post->ping_status;
+ $display_data['link'] = $this->get_permalink();
+ $display_data['distributor_original_site_name'] = $this->source_site['name'];
+ $display_data['distributor_original_site_url'] = $this->source_site['home_url'];
return $display_data;
}
From d0592a57f3b4b1509937261f41dad3163a3ee39c Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 14:29:55 +1100
Subject: [PATCH 13/57] Modify method generating WP_Post object.
---
.../WordPressExternalConnection.php | 53 ++++---------------
1 file changed, 9 insertions(+), 44 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 9cecedf6c..6e5960d8f 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -940,55 +940,18 @@ private function not_distributor_internal_post_type( $post_type ) {
* @return \WP_Post
*/
private function to_wp_post( $post ) {
- $obj = new \stdClass();
+ $obj = (object) $post;
- $obj->ID = $post['id'];
- $obj->post_title = $post['title']['rendered'];
-
- if ( isset( $post['excerpt']['raw'] ) ) {
- $obj->post_excerpt = $post['excerpt']['raw'];
- } elseif ( isset( $post['excerpt']['rendered'] ) ) {
- $obj->post_excerpt = $post['excerpt']['rendered'];
- } else {
- $obj->post_excerpt = '';
- }
-
- $obj->post_status = 'draft';
- $obj->post_author = get_current_user_id();
-
- $obj->post_password = $post['password'];
- $obj->post_date = $post['date'];
- $obj->post_date_gmt = $post['date_gmt'];
- $obj->guid = $post['guid']['rendered'];
- $obj->post_modified = $post['modified'];
- $obj->post_modified_gmt = $post['modified_gmt'];
- $obj->post_type = $post['type'];
- $obj->link = $post['link'];
- $obj->comment_status = $post['comment_status'];
- $obj->ping_status = $post['ping_status'];
-
- if ( isset( $post['content']['raw'] ) ) {
- // Use raw content if remote post uses Gutenberg and the local post type is compatible with it.
- $obj->post_content = Utils\dt_use_block_editor_for_post_type( $obj->post_type ) && isset( $post['is_using_gutenberg'] ) ?
- $post['content']['raw'] :
- Utils\get_processed_content( $post['content']['raw'] );
- } elseif ( isset( $post['content']['rendered'] ) ) {
- $obj->post_content = $post['content']['rendered'];
- } else {
- $obj->post_content = '';
- }
-
-
- /**
+ /*
* These will only be set if Distributor is active on the other side
*/
- $obj->meta = ( ! empty( $post['distributor_meta'] ) ) ? $post['distributor_meta'] : [];
- $obj->terms = ( ! empty( $post['distributor_terms'] ) ) ? $post['distributor_terms'] : [];
- $obj->media = ( ! empty( $post['distributor_media'] ) ) ? $post['distributor_media'] : [];
$obj->original_site_name = ( ! empty( $post['distributor_original_site_name'] ) ) ? $post['distributor_original_site_name'] : null;
$obj->original_site_url = ( ! empty( $post['distributor_original_site_url'] ) ) ? $post['distributor_original_site_url'] : null;
- $obj->full_connection = ( ! empty( $post['full_connection'] ) );
+ // Unset these as they are renamed above.
+ unset( $obj->distributor_original_site_name );
+ unset( $obj->distributor_original_site_url );
+
/**
* Filter the post item.
@@ -1001,7 +964,9 @@ private function to_wp_post( $post ) {
*
* @return {WP_Post} The WP_Post that is being pushed.
*/
- return apply_filters( 'dt_item_mapping', new \WP_Post( $obj ), $post, $this );
+ $post_object = apply_filters( 'dt_item_mapping', new \WP_Post( $obj ), $post, $this );
+
+ return $post_object;
}
/**
From 1d47baa2f2c014259fe002f4a0f4c395bad6a568 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 14:32:33 +1100
Subject: [PATCH 14/57] CS Fix.
---
includes/rest-api.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 7e0477d7d..d6a2204b9 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -279,7 +279,7 @@ function( $post_type ) {
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
),
- 'post_status' => array(
+ 'post_status' => array(
'default' => array( 'publish' ),
'description' => esc_html__( 'Limit result set to content assigned one or more statuses.', 'distributor' ),
'type' => array( 'array', 'string' ),
From 7407ebe3c2778c73b6520238350cb7d69aa2a88d Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 15:42:55 +1100
Subject: [PATCH 15/57] Use false for false check.
---
includes/rest-api.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index d6a2204b9..99f90052a 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -352,7 +352,7 @@ function get_pull_content_permissions( $request ) {
* to pass through this check.
*/
if (
- true !== Utils\is_development_version()
+ false === Utils\is_development_version()
&& null !== $request->get_param( 'distributor_request' )
&& (
null === $request->get_header( 'X-Distributor-Version' )
From b354d48066007503f0ff2cbd97dc5ca5b3176114 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 22 Mar 2023 15:44:32 +1100
Subject: [PATCH 16/57] Improve variable names.
---
includes/rest-api.php | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 99f90052a..1308a04d8 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -367,17 +367,17 @@ function get_pull_content_permissions( $request ) {
}
- $post_type = $request->get_param( 'post_type' );
- if ( empty( $post_type ) ) {
+ $post_types = $request->get_param( 'post_type' );
+ if ( empty( $post_types ) ) {
return false;
}
- if ( is_string( $post_type ) ) {
- $post_type = array( $post_type );
+ if ( is_string( $post_types ) ) {
+ $post_types = array( $post_types );
}
- foreach ( $post_type as $single_post_type ) {
- $post_type_object = get_post_type_object( $single_post_type );
+ foreach ( $post_types as $post_type ) {
+ $post_type_object = get_post_type_object( $post_type );
if ( ! $post_type_object ) {
return false;
}
From b888f411fcbd6c1e2e043ba18ab7cbc1697cb9d7 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 23 Mar 2023 13:30:07 +1100
Subject: [PATCH 17/57] Add version constant to bootstrap file.
---
.github/release-pull-request-template.md | 2 +-
tests/php/bootstrap.php | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/release-pull-request-template.md b/.github/release-pull-request-template.md
index 84efa24f2..8dd1bdbec 100644
--- a/.github/release-pull-request-template.md
+++ b/.github/release-pull-request-template.md
@@ -1,5 +1,5 @@
- [x] Branch: Starting from `develop`, create a release branch named `release/X.Y.Z` for your changes.
-- [ ] Version bump: Bump the version number in `distributor.php`, `package.json`, and `readme.txt` if it does not already reflect the version being released. In `distributor.php` update both the plugin "Version:" property and the plugin `DT_VERSION` constant.
+- [ ] Version bump: Bump the version number in `distributor.php`, `package.json`, `readme.txt` and `tests/php/bootstrap.php` if it does not already reflect the version being released. In `distributor.php` update both the plugin "Version:" property and the plugin `DT_VERSION` constant.
- [ ] New files: Ensure any new files, especially in the vendor folder, are correctly included in `webpack.config.release.js`.
- [ ] Changelog: Add/update the changelog in `CHANGELOG.md`.
- [ ] Props: Update `CREDITS.md` file with any new contributors, confirm maintainers are accurate.
diff --git a/tests/php/bootstrap.php b/tests/php/bootstrap.php
index 16602dd84..aa1585f2b 100644
--- a/tests/php/bootstrap.php
+++ b/tests/php/bootstrap.php
@@ -10,6 +10,7 @@
WP_Mock::bootstrap();
define( 'DT_PLUGIN_PATH', dirname( __DIR__, 2 ) );
+define( 'DT_VERSION', '1.9.1' );
require_once __DIR__ . '/includes/common.php';
require_once __DIR__ . '/includes/TestCase.php';
From dc307381bb9a0cd5c20372bd0bd2507248cfa13f Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 23 Mar 2023 14:44:26 +1100
Subject: [PATCH 18/57] Add mocks.
---
tests/php/NetworkSiteConnectionsTest.php | 53 ++++++++++++++++++-
tests/php/WordPressExternalConnectionTest.php | 1 +
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/tests/php/NetworkSiteConnectionsTest.php b/tests/php/NetworkSiteConnectionsTest.php
index 14e3f5aa8..ad9094011 100644
--- a/tests/php/NetworkSiteConnectionsTest.php
+++ b/tests/php/NetworkSiteConnectionsTest.php
@@ -237,6 +237,24 @@ public function test_push() {
* @runInSeparateProcess
*/
public function test_pull() {
+ $this->setup_post_meta_mock( array(
+ 'dt_connection_map' => array( array() )
+ ) );
+ \WP_Mock::userFunction(
+ 'get_bloginfo',
+ array(
+ 'return' => function( $info ) {
+ switch ( $info ) {
+ case 'charset':
+ return 'UTF-8';
+ case 'name':
+ return 'Test Internal Origin';
+ default:
+ return '';
+ }
+ },
+ )
+ );
$this->connection_obj->site->blog_id = 2;
@@ -252,11 +270,44 @@ public function test_pull() {
'get_post', [
'return' => (object) [
'ID' => 111,
- 'post_tite' => 'My post title',
+ 'post_title' => 'My post title',
+ 'post_name' => 'my-post-title',
+ 'post_type' => 'post',
+ 'post_status' => 'publish',
+ 'post_content' => 'My post content',
+ 'post_excerpt' => 'My post excerpt',
'meta' => [],
],
]
);
+ \WP_Mock::userFunction(
+ 'get_the_title', [
+ 'return' => 'My post title',
+ ]
+ );
+ \WP_Mock::userFunction(
+ 'has_blocks',
+ array(
+ 'return' => false,
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_attached_media',
+ array(
+ 'return' => array(),
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_post_thumbnail_id',
+ array(
+ 'return' => false,
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_current_user_id', [
+ 'return' => 1,
+ ]
+ );
\WP_Mock::userFunction(
'get_permalink', [
diff --git a/tests/php/WordPressExternalConnectionTest.php b/tests/php/WordPressExternalConnectionTest.php
index b74d1bc48..c6878d78e 100644
--- a/tests/php/WordPressExternalConnectionTest.php
+++ b/tests/php/WordPressExternalConnectionTest.php
@@ -254,6 +254,7 @@ public function test_push() {
* @runInSeparateProcess
*/
public function test_pull() {
+ $this->setup_post_meta_mock( array() );
$post_id = 123;
\WP_Mock::userFunction( 'wp_remote_retrieve_response_code' );
From e13c4400d7f3f2bd672ed47b9d1573d0cf25f798 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 24 Mar 2023 13:07:28 +1100
Subject: [PATCH 19/57] Assign post data to post array.
---
includes/classes/InternalConnections/NetworkSiteConnection.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index 47ac1935f..8def359ca 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -274,7 +274,7 @@ public function pull( $items ) {
}
$post_props = $post;
- $post_array = array();
+ $post_array = $post_props;
$current_blog_id = get_current_blog_id();
if ( ! empty( $post_props['meta']['dt_connection_map'] ) ) {
From 3f4ba027e9b6a6c69f0eb72c8b36bc1524a97157 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 24 Mar 2023 13:24:25 +1100
Subject: [PATCH 20/57] Include connection map in remote_get.
---
includes/classes/InternalConnections/NetworkSiteConnection.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index 8def359ca..94cf1dedd 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -591,6 +591,8 @@ public function remote_get( $args = array(), $new_post_args = array() ) {
} else {
$dt_post = new DistributorPost( $post );
$formatted_post = $dt_post->to_insert( $new_post_args );
+ // The pull method requires the connection map despite it being on the deny list.
+ $formatted_post['meta']['dt_connection_map'] = get_post_meta( $id, 'dt_connection_map', true );
}
restore_current_blog();
From dd8dd9c1ffd19d5c6d23599938444275fb09920d Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 29 Mar 2023 12:57:54 +1100
Subject: [PATCH 21/57] Update post ID and post URL manually.
---
includes/classes/InternalConnections/NetworkSiteConnection.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index 94cf1dedd..7cf127ace 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -302,6 +302,8 @@ public function pull( $items ) {
if ( ! is_wp_error( $new_post_id ) ) {
update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $this->site->blog_id );
update_post_meta( $new_post_id, 'dt_syndicate_time', time() );
+ update_post_meta( $new_post_id, 'dt_original_post_id', $new_post_args['meta_input']['dt_original_post_id'] );
+ update_post_meta( $new_post_id, 'dt_original_post_url', $new_post_args['meta_input']['dt_original_post_url'] );
/**
* Allow bypassing of all meta processing.
From 3c4d1877676d63c9066ab40f66303f36bf6b4bc4 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 29 Mar 2023 13:08:58 +1100
Subject: [PATCH 22/57] Update Source Post ID.
---
tests/php/NetworkSiteConnectionsTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/php/NetworkSiteConnectionsTest.php b/tests/php/NetworkSiteConnectionsTest.php
index ad9094011..6a70c3fe9 100644
--- a/tests/php/NetworkSiteConnectionsTest.php
+++ b/tests/php/NetworkSiteConnectionsTest.php
@@ -324,7 +324,7 @@ public function test_pull() {
\WP_Mock::userFunction(
'update_post_meta', [
'times' => 1,
- 'args' => [ \WP_Mock\Functions::type( 'int' ), 'dt_original_post_id', 2 ],
+ 'args' => [ \WP_Mock\Functions::type( 'int' ), 'dt_original_post_id', 111 ],
'return' => [],
]
);
From 76fa01a1dcec87cf10ec7511d3b37bdcc4a63bb6 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 29 Mar 2023 13:33:22 +1100
Subject: [PATCH 23/57] Remove mock that uses the general post_meta mock.
---
tests/php/NetworkSiteConnectionsTest.php | 8 --------
1 file changed, 8 deletions(-)
diff --git a/tests/php/NetworkSiteConnectionsTest.php b/tests/php/NetworkSiteConnectionsTest.php
index 6a70c3fe9..d1947a40a 100644
--- a/tests/php/NetworkSiteConnectionsTest.php
+++ b/tests/php/NetworkSiteConnectionsTest.php
@@ -353,14 +353,6 @@ public function test_pull() {
]
);
- \WP_Mock::userFunction(
- 'get_post_meta', [
- 'times' => 1,
- 'args' => [ \WP_Mock\Functions::type( 'int' ), 'dt_connection_map', true ],
- 'return' => [],
- ]
- );
-
\WP_Mock::userFunction(
'update_post_meta', [
'times' => 1,
From 97dd3a19e523c64d5fc8224b804ddaaa5f1ac20c Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 29 Mar 2023 13:41:31 +1100
Subject: [PATCH 24/57] Add mocks required by new code structure.
---
tests/php/NetworkSiteConnectionsTest.php | 56 ++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/tests/php/NetworkSiteConnectionsTest.php b/tests/php/NetworkSiteConnectionsTest.php
index d1947a40a..85f3b61c9 100644
--- a/tests/php/NetworkSiteConnectionsTest.php
+++ b/tests/php/NetworkSiteConnectionsTest.php
@@ -423,10 +423,66 @@ public function test_remote_get() {
'return' => (object) [
'ID' => 111,
'post_title' => 'my title',
+ 'post_name' => 'my-title',
+ 'post_type' => 'post',
+ 'post_status' => 'publish',
+ 'post_content' => 'My post content',
+ 'post_excerpt' => 'My post excerpt',
],
]
);
+ \WP_Mock::userFunction(
+ 'get_bloginfo',
+ array(
+ 'return' => function( $info ) {
+ switch ( $info ) {
+ case 'charset':
+ return 'UTF-8';
+ case 'name':
+ return 'Test Internal Origin';
+ default:
+ return '';
+ }
+ },
+ )
+ );
+
+ \WP_Mock::userFunction(
+ 'get_current_blog_id', [
+ 'return' => 1,
+ ]
+ );
+
+ \WP_Mock::userFunction(
+ 'get_the_title', [
+ 'return' => 'my title',
+ ]
+ );
+ \WP_Mock::userFunction(
+ 'has_blocks',
+ array(
+ 'return' => false,
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_attached_media',
+ array(
+ 'return' => array(),
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_post_thumbnail_id',
+ array(
+ 'return' => false,
+ )
+ );
+ \WP_Mock::userFunction(
+ 'get_current_user_id', [
+ 'return' => 1,
+ ]
+ );
+
$this->assertArrayHasKey(
'post_title', (array) $this->connection_obj->remote_get(
[
From 40d03c619c72eb7310ca649b21848590dff77aa3 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 29 Mar 2023 13:55:32 +1100
Subject: [PATCH 25/57] Add version header to various HTTP request mocks.
---
tests/php/SubscriptionsTest.php | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/php/SubscriptionsTest.php b/tests/php/SubscriptionsTest.php
index e46f25e37..089599def 100644
--- a/tests/php/SubscriptionsTest.php
+++ b/tests/php/SubscriptionsTest.php
@@ -98,6 +98,9 @@ public function test_delete_subscribed_post() {
[
'timeout' => 5,
'blocking' => \Distributor\Utils\is_dt_debug(),
+ 'headers' => [
+ 'X-Distributor-Version' => DT_VERSION,
+ ],
'body' => [
'post_id' => $remote_post_id,
'signature' => $signature,
@@ -375,6 +378,7 @@ public function test_send_notifications_no_remote_post() {
] ),
'headers' => [
'Content-Type' => 'application/json',
+ 'X-Distributor-Version' => DT_VERSION,
],
],
],
@@ -566,6 +570,7 @@ public function test_send_notifications_remote_post_exists() {
] ),
'headers' => [
'Content-Type' => 'application/json',
+ 'X-Distributor-Version' => DT_VERSION,
]
],
],
@@ -761,6 +766,9 @@ public function test_create_remote_subscription() {
[
'timeout' => 5,
'blocking' => \Distributor\Utils\is_dt_debug(),
+ 'headers' => [
+ 'X-Distributor-Version' => DT_VERSION,
+ ],
'body' => [
'post_id' => $remote_post_id,
'remote_post_id' => $post_id,
From a6db663a42bd951056182c3e02a522e1c793aad2 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 4 Apr 2023 15:02:09 +1000
Subject: [PATCH 26/57] Always use POST requests on pull screen.
---
.../ExternalConnections/WordPressExternalConnection.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 6e5960d8f..c4dd13ea5 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -167,8 +167,8 @@ public function remote_get( $args = array() ) {
}
}
- // When running a query for the Pull screen with excluded items, make a POST request instead
- if ( empty( $id ) && isset( $args['post__not_in'] ) && isset( $args['dt_pull_list'] ) ) {
+ // When running a query for the Pull screen, make a POST request instead
+ if ( empty( $id ) && isset( $args['dt_pull_list'] ) ) {
$query_args['post_type'] = isset( $post_type ) ? $post_type : 'post';
$query_args['posts_per_page'] = isset( $posts_per_page ) ? $posts_per_page : 20;
From db58d8aa06783db72ff11ba200813b1b2528dc8b Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 6 Apr 2023 10:59:06 +1000
Subject: [PATCH 27/57] Add order parameter to the get pull content REST
endpoint.
---
includes/rest-api.php | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 1308a04d8..5535e8789 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -327,6 +327,12 @@ function( $post_type ) {
return $param;
},
),
+ 'order' => array(
+ 'description' => esc_html__( 'Order sort attribute ascending or descending.', 'distributor' ),
+ 'type' => 'string',
+ 'default' => 'desc',
+ 'enum' => array( 'asc', 'desc' ),
+ ),
);
}
@@ -599,6 +605,7 @@ function get_pull_content_list( $request ) {
'paged' => isset( $request['page'] ) ? $request['page'] : 1,
'post_type' => isset( $request['post_type'] ) ? $request['post_type'] : 'post',
'post_status' => isset( $request['post_status'] ) ? $request['post_status'] : array( 'any' ),
+ 'order' => ! empty( $request['order'] ) ? strtoupper( $request['order'] ) : 'DESC',
];
if ( ! empty( $request['search'] ) ) {
From 929547b0ec31bc2cc1d12aff77aba21d4d2717af Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 6 Apr 2023 15:26:20 +1000
Subject: [PATCH 28/57] Add orderby parameter to the get pull content REST
endpoint.
---
includes/rest-api.php | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 5535e8789..8d91d3510 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -333,6 +333,22 @@ function( $post_type ) {
'default' => 'desc',
'enum' => array( 'asc', 'desc' ),
),
+ 'orderby' => array(
+ 'description' => esc_html__( 'Sort collection by object attribute.', 'distributor' ),
+ 'type' => 'string',
+ 'default' => 'date',
+ 'enum' => array(
+ 'author',
+ 'date',
+ 'id',
+ 'include',
+ 'modified',
+ 'parent',
+ 'relevance',
+ 'slug',
+ 'title',
+ ),
+ ),
);
}
@@ -609,7 +625,8 @@ function get_pull_content_list( $request ) {
];
if ( ! empty( $request['search'] ) ) {
- $args['s'] = rawurldecode( $request['search'] );
+ $args['s'] = rawurldecode( $request['search'] );
+ $args['orderby'] = 'relevance';
}
if ( ! empty( $request['exclude'] ) ) {
@@ -620,6 +637,30 @@ function get_pull_content_list( $request ) {
$args['post__in'] = $request['include'];
}
+ if ( ! empty( $request['orderby'] ) ) {
+ $args['orderby'] = $request['orderby'];
+
+ if ( 'id' === $request['orderby'] ) {
+ // Flip the case to uppercase for WP_Query.
+ $args['orderby'] = 'ID';
+ } elseif ( 'slug' === $request['orderby'] ) {
+ $args['orderby'] = 'name';
+ } elseif ( 'relevance' === $request['orderby'] ) {
+ $args['orderby'] = 'relevance';
+
+ // If ordering by relevance, a search term must be defined.
+ if ( empty( $request['search'] ) ) {
+ return new WP_Error(
+ 'rest_no_search_term_defined',
+ __( 'You need to define a search term to order by relevance.', 'distributor' ),
+ array( 'status' => 400 )
+ );
+ }
+ } elseif ( 'include' === $request['orderby'] ) {
+ $args['orderby'] = 'post__in';
+ }
+ }
+
/**
* Filters WP_Query arguments when querying posts via the REST API.
*
From 918af12f86fb23c13c2f31fa8da6b1513bcacf25 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 6 Apr 2023 15:28:57 +1000
Subject: [PATCH 29/57] Update docblock for new parameters.
---
includes/rest-api.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 8d91d3510..88c21608f 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -159,7 +159,9 @@ function register_rest_routes() {
}
/**
- * Set the accepted arguments for the pull content list endpoint
+ * Set the accepted arguments for the pull content list endpoint.
+ *
+ * @since x.x.x Introduced the include, order and orderby arguments.
*
* @return array
*/
From 0f6df4979c6debaebaaf5cd84e55559da4631dec Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:12:13 +1000
Subject: [PATCH 30/57] Fix misnamed date properties.
---
includes/classes/DistributorPost.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/includes/classes/DistributorPost.php b/includes/classes/DistributorPost.php
index 4766c6e6e..d0cc43050 100644
--- a/includes/classes/DistributorPost.php
+++ b/includes/classes/DistributorPost.php
@@ -834,10 +834,10 @@ protected function to_pull_list( $args = array() ) {
// Additional information required for pull screen.
$display_data['ID'] = $this->post->ID;
- $display_data['date'] = $this->post->post_date;
- $display_data['date_gmt'] = $this->post->post_date_gmt;
- $display_data['modified'] = $this->post->post_modified;
- $display_data['modified_gmt'] = $this->post->post_modified_gmt;
+ $display_data['post_date'] = $this->post->post_date;
+ $display_data['post_date_gmt'] = $this->post->post_date_gmt;
+ $display_data['post_modified'] = $this->post->post_modified;
+ $display_data['post_modified_gmt'] = $this->post->post_modified_gmt;
$display_data['post_password'] = $this->post->post_password;
$display_data['guid'] = $this->post->guid;
$display_data['comment_status'] = $this->post->comment_status;
From 9958f8c6aa200278dde411dc2acdec9235b487c9 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:12:53 +1000
Subject: [PATCH 31/57] Avoid conflicting include and exclude clauses.
---
includes/rest-api.php | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 88c21608f..d371f6b97 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -631,11 +631,17 @@ function get_pull_content_list( $request ) {
$args['orderby'] = 'relevance';
}
- if ( ! empty( $request['exclude'] ) ) {
+ if ( ! empty( $request['exclude'] ) && ! empty( $request['include'] ) ) {
+ /*
+ * Use only `post__in` if both `include` and `exclude` are populated.
+ *
+ * Excluded posts take priority over included posts, if the same post is
+ * included in both arrays, it will be excluded.
+ */
+ $args['post__in'] = array_diff( $request['include'], $request['exclude'] );
+ } elseif ( ! empty( $request['exclude'] ) ) {
$args['post__not_in'] = $request['exclude'];
- }
-
- if ( ! empty( $request['include'] ) ) {
+ } elseif ( ! empty( $request['include'] ) ) {
$args['post__in'] = $request['include'];
}
From ec02077516587b8a9c8a57fa29322ef79053b5ab Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:15:07 +1000
Subject: [PATCH 32/57] Use custom endpoint for pulling single post.
---
.../WordPressExternalConnection.php | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index c4dd13ea5..11c1fec80 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -284,7 +284,20 @@ public function remote_get( $args = array() ) {
}
if ( ! empty( $id ) ) {
- $posts_url = untrailingslashit( $types_urls[ $post_type ] ) . '/' . $id . '/?context=' . $context;
+ $query_args = array(
+ 'include' => (int) $id,
+ 'post_type' => isset( $args['post_type'] ) ? $args['post_type'] : 'any',
+ );
+ $posts_response = $this->remote_post(
+ untrailingslashit( $this->base_url ) . '/' . self::$namespace . '/distributor/list-pull-content',
+ $query_args
+ );
+
+ if ( is_wp_error( $posts_response ) ) {
+ return $posts_response;
+ }
+
+ return $posts_response['items'][0];
} else {
$posts_url = untrailingslashit( $types_urls[ $post_type ] ) . '/?' . $args_str;
}
From 1f6de6e8acbdbe81a29c3e6bbcfe506bd86b5bc0 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:17:00 +1000
Subject: [PATCH 33/57] Unset remote site details on one location.
---
.../WordPressExternalConnection.php | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 11c1fec80..02ef7a9da 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -522,26 +522,21 @@ public function pull( $items ) {
$post_array[ $key ] = $value;
}
+ // Unset data from remote site.
+ unset( $post_array['ID'] );
+ unset( $post_array['post_parent'] );
+ unset( $post_array['post_date'] );
+ unset( $post_array['post_date_gmt'] );
+ unset( $post_array['post_modified'] );
+ unset( $post_array['post_modified_gmt'] );
if ( ! empty( $item_array['post_id'] ) ) {
$post_array['ID'] = $item_array['post_id'];
- } else {
- unset( $post_array['ID'] );
- }
-
- if ( isset( $post_array['post_parent'] ) ) {
- unset( $post_array['post_parent'] );
}
if ( ! empty( $item_array['post_status'] ) ) {
$post_array['post_status'] = $item_array['post_status'];
}
- // Remove date stuff
- unset( $post_array['post_date'] );
- unset( $post_array['post_date_gmt'] );
- unset( $post_array['post_modified'] );
- unset( $post_array['post_modified_gmt'] );
-
/**
* Filter the arguments passed into wp_insert_post during a pull.
*
From cb79bf7764ef77a01c3e1807c30bf11aa27a3e34 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:19:12 +1000
Subject: [PATCH 34/57] Use custom endpoint for pulling individual posts. Do in
bulk.
---
.../WordPressExternalConnection.php | 29 ++++++++++++++-----
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 02ef7a9da..fd2940f50 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -502,18 +502,31 @@ public function remote_post( $url = '', $args = array() ) {
public function pull( $items ) {
$created_posts = array();
+ $remote_post_args = array(
+ 'include' => array(),
+ 'post_type' => array(),
+ );
foreach ( $items as $item_array ) {
- $post = $this->remote_get(
- [
- 'id' => $item_array['remote_post_id'],
- 'post_type' => $item_array['post_type'],
- ]
- );
+ $remote_post_args['include'][] = $item_array['remote_post_id'];
+ $remote_post_args['post_type'][] = $item_array['post_type'];
+ }
+ $remote_post_args['include'] = array_unique( $remote_post_args['include'] );
+ $remote_post_args['post_type'] = array_unique( $remote_post_args['post_type'] );
+ $remote_post_args['posts_per_page'] = count( $remote_post_args['include'] );
+
+ // Get all remote posts in a single request.
+ $remote_posts = $this->remote_post(
+ untrailingslashit( $this->base_url ) . '/' . self::$namespace . '/distributor/list-pull-content',
+ $remote_post_args
+ );
- if ( is_wp_error( $post ) ) {
- $created_posts[] = $post;
+ foreach ( $items as $item_array ) {
+ $post = wp_list_filter( $remote_posts['items'], array( 'ID' => $item_array['remote_post_id'] ) );
+ if ( empty( $post ) ) {
+ $created_posts[] = new \WP_Error( 'no-post', esc_html__( 'No post found.', 'distributor' ) );
continue;
}
+ $post = $post[0];
$post_props = get_object_vars( $post );
$post_array = array();
From 8111b781553aaedcac13a8e6d4598cf9a7290156 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 14:19:36 +1000
Subject: [PATCH 35/57] Use `wp_update_post()` when updating existing posts.
---
.../ExternalConnections/WordPressExternalConnection.php | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index fd2940f50..a559427d8 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -535,6 +535,7 @@ public function pull( $items ) {
$post_array[ $key ] = $value;
}
+ $update = false;
// Unset data from remote site.
unset( $post_array['ID'] );
unset( $post_array['post_parent'] );
@@ -542,7 +543,9 @@ public function pull( $items ) {
unset( $post_array['post_date_gmt'] );
unset( $post_array['post_modified'] );
unset( $post_array['post_modified_gmt'] );
+
if ( ! empty( $item_array['post_id'] ) ) {
+ $update = true;
$post_array['ID'] = $item_array['post_id'];
}
@@ -564,7 +567,11 @@ public function pull( $items ) {
* @return {array} The post data to be inserted.
*/
$new_post_args = Utils\post_args_allow_list( apply_filters( 'dt_pull_post_args', $post_array, $item_array['remote_post_id'], $post, $this ) );
- $new_post = wp_insert_post( wp_slash( $new_post_args ) );
+ if ( $update ) {
+ $new_post = wp_update_post( wp_slash( $new_post_args ) );
+ } else {
+ $new_post = wp_insert_post( wp_slash( $new_post_args ) );
+ }
update_post_meta( $new_post, 'dt_original_post_id', (int) $item_array['remote_post_id'] );
update_post_meta( $new_post, 'dt_original_source_id', (int) $this->id );
From 958c8e02bf4d91e4d7cd9d8551e0e9d4e0c963a2 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 15:29:15 +1000
Subject: [PATCH 36/57] Exit if remote request fails.
---
.../ExternalConnections/WordPressExternalConnection.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index a559427d8..7afecaa95 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -520,6 +520,10 @@ public function pull( $items ) {
$remote_post_args
);
+ if ( is_wp_error( $remote_posts ) ) {
+ return $remote_posts;
+ }
+
foreach ( $items as $item_array ) {
$post = wp_list_filter( $remote_posts['items'], array( 'ID' => $item_array['remote_post_id'] ) );
if ( empty( $post ) ) {
From 3080b9f79a42358baf3ccc7f77660843e175c041 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 15:29:36 +1000
Subject: [PATCH 37/57] Use correct names for original site data.
---
.../ExternalConnections/WordPressExternalConnection.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 7afecaa95..3555bafaa 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -581,8 +581,8 @@ public function pull( $items ) {
update_post_meta( $new_post, 'dt_original_source_id', (int) $this->id );
update_post_meta( $new_post, 'dt_syndicate_time', time() );
update_post_meta( $new_post, 'dt_original_post_url', esc_url_raw( $post_array['link'] ) );
- update_post_meta( $new_post, 'dt_original_site_name', sanitize_text_field( $post_array['original_site_name'] ) );
- update_post_meta( $new_post, 'dt_original_site_url', sanitize_text_field( $post_array['original_site_url'] ) );
+ update_post_meta( $new_post, 'dt_original_site_name', sanitize_text_field( $post_array['distributor_original_site_name'] ) );
+ update_post_meta( $new_post, 'dt_original_site_url', sanitize_text_field( $post_array['distributor_original_site_url'] ) );
if ( ! empty( $post->post_parent ) ) {
update_post_meta( $new_post, 'dt_original_post_parent', (int) $post->post_parent );
From 83ecd7c3c85f34cd43211e31e4e0731b35962ddd Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 13 Apr 2023 15:29:59 +1000
Subject: [PATCH 38/57] Fix pull test.
---
tests/php/WordPressExternalConnectionTest.php | 25 ++----
tests/php/includes/common.php | 84 +++++++++++--------
2 files changed, 59 insertions(+), 50 deletions(-)
diff --git a/tests/php/WordPressExternalConnectionTest.php b/tests/php/WordPressExternalConnectionTest.php
index c6878d78e..299ba2b47 100644
--- a/tests/php/WordPressExternalConnectionTest.php
+++ b/tests/php/WordPressExternalConnectionTest.php
@@ -257,12 +257,13 @@ public function test_pull() {
$this->setup_post_meta_mock( array() );
$post_id = 123;
- \WP_Mock::userFunction( 'wp_remote_retrieve_response_code' );
\WP_Mock::userFunction( 'untrailingslashit' );
\WP_Mock::userFunction( 'sanitize_text_field' );
remote_get_setup();
+ \WP_Mock::passthruFunction( 'wp_slash' );
+ \WP_Mock::passthruFunction( 'update_post_meta' );
\WP_Mock::userFunction( 'get_current_user_id' );
\WP_Mock::userFunction( 'delete_post_meta' );
@@ -284,24 +285,16 @@ public function test_pull() {
]
);
- \WP_Mock::userFunction(
- 'add_query_arg', [
- 'times' => 1,
+ $pull_actual = $this->connection->pull(
+ [
+ [
+ 'remote_post_id' => $post_id,
+ 'post_type' => 'post',
+ ],
]
);
- $this->assertTrue(
- is_array(
- $this->connection->pull(
- [
- [
- 'remote_post_id' => $post_id,
- 'post_type' => 'post',
- ],
- ]
- )
- )
- );
+ $this->assertIsArray( $pull_actual );
}
/**
diff --git a/tests/php/includes/common.php b/tests/php/includes/common.php
index d0c59f04f..6a4a21f40 100644
--- a/tests/php/includes/common.php
+++ b/tests/php/includes/common.php
@@ -157,50 +157,66 @@ function remote_get_setup() {
\WP_Mock::userFunction( 'get_option' );
- $post_type = 'post';
- $links = [
- '_links' => [
- 'wp:items' => [
- [ 'href' => 'http://url.com' ],
+ $rest_response = [
+ [
+ 'post_title' => 'My post title',
+ 'post_name' => 'my-post-title',
+ 'post_type' => 'post',
+ 'post_content' => '',
+ 'post_excerpt' => '',
+ 'post_status' => 'publish',
+ 'terms' => [],
+ 'meta' => [],
+ 'media' => [],
+ 'post_author' => 1,
+ 'meta_input' => [
+ 'dt_original_post_id' => 123,
+ 'dt_original_post_url' => 'http://example.com/2023/04/11/my-post-title/',
],
+ 'ID' => 123,
+ 'post_date' => '2023-04-11 05:40:43',
+ 'post_date_gmt' => '2023-04-11 05:40:43',
+ 'post_modified' => '2023-04-11 05:40:43',
+ 'post_modified_gmt' => '2023-04-11 05:40:43',
+ 'post_password' => '',
+ 'guid' => 'http://example.com/?p=123',
+ 'comment_status' => 'open',
+ 'ping_status' => 'open',
+ 'link' => 'http://example.com/2023/04/11/my-post-title/',
+ 'distributor_original_site_name' => 'My site name',
+ 'distributor_original_site_url' => 'http://example.com/',
],
];
\WP_Mock::userFunction(
- 'wp_remote_request', [
- 'return' => json_encode(
- [
- $post_type => $links,
- ]
- ),
+ 'wp_remote_post', [
+ 'return' => new stdClass(),
+ ]
+ );
+
+ \WP_Mock::userFunction(
+ 'wp_remote_retrieve_headers', [
+ 'return' => [
+ 'X-Distributor' => 'yes',
+ ],
]
);
- // todo: the response is missing post_type
\WP_Mock::userFunction(
'wp_remote_retrieve_body', [
- 'return' => json_encode(
- [
- 'id' => 123,
- 'title' => [ 'rendered' => 'My post title' ],
- 'content' => [ 'rendered' => '', 'raw' => '' ],
- 'excerpt' => [ 'rendered' => '' ],
- 'date' => '',
- 'date_gmt' => '',
- 'guid' => [ 'rendered' => '' ],
- 'modified' => '',
- 'modified_gmt' => '',
- 'type' => '',
- 'link' => '',
- 'distributor_meta' => [],
- 'distributor_terms' => [],
- 'distributor_media' => [],
- $post_type => $links,
- 'comment_status' => 'open',
- 'ping_status' => 'open',
- 'password' => '',
- ]
- ),
+ 'return' => json_encode( $rest_response ),
+ ]
+ );
+
+ \WP_Mock::userFunction(
+ 'wp_remote_retrieve_response_code', [
+ 'return' => 200,
+ ]
+ );
+
+ \WP_Mock::userFunction(
+ 'wp_list_filter', [
+ 'return' => [ new WP_Post( (object) $rest_response[0] ) ],
]
);
}
From 619d50a102b7281099c1658c5be9aac42e6c6275 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 15:58:51 +1000
Subject: [PATCH 39/57] Always use post request for list screen.
---
.../classes/ExternalConnections/WordPressExternalConnection.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 3555bafaa..15e270f50 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -168,7 +168,7 @@ public function remote_get( $args = array() ) {
}
// When running a query for the Pull screen, make a POST request instead
- if ( empty( $id ) && isset( $args['dt_pull_list'] ) ) {
+ if ( empty( $id ) ) {
$query_args['post_type'] = isset( $post_type ) ? $post_type : 'post';
$query_args['posts_per_page'] = isset( $posts_per_page ) ? $posts_per_page : 20;
From a2b95c49fda1ba83b7c4b47f3c278302d2d0e537 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 15:59:39 +1000
Subject: [PATCH 40/57] Remove types check, pull no longer uses WP default
endpoints.
---
.../WordPressExternalConnection.php | 48 -------------------
1 file changed, 48 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 15e270f50..f8622c751 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -180,54 +180,6 @@ public function remote_get( $args = array() ) {
return $posts_response;
}
- static $types_urls;
- $types_urls = array();
-
- if ( empty( $types_urls[ $post_type ] ) ) {
- /**
- * First let's get the actual route if not cached. We don't know the "plural" of our post type
- */
-
- /**
- * Todo: This should be cached in a transient
- */
-
- $path = self::$namespace;
-
- $types_path = untrailingslashit( $this->base_url ) . '/' . $path . '/types';
-
- $types_response = Utils\remote_http_request(
- $types_path,
- $this->auth_handler->format_get_args( array( 'timeout' => self::$timeout ) )
- );
-
- if ( is_wp_error( $types_response ) ) {
- return $types_response;
- }
-
- if ( 404 === wp_remote_retrieve_response_code( $types_response ) ) {
- return new \WP_Error( 'bad-endpoint', esc_html__( 'Could not connect to API endpoint.', 'distributor' ) );
- }
-
- $types_body = wp_remote_retrieve_body( $types_response );
-
- if ( empty( $types_body ) ) {
- return new \WP_Error( 'no-response-body', esc_html__( 'Response body is empty.', 'distributor' ) );
- }
-
- $types_body_array = json_decode( $types_body, true );
-
- if ( empty( $types_body_array ) || empty( $types_body_array[ $post_type ] ) ) {
- return new \WP_Error( 'no-pull-post-type', esc_html__( 'Could not determine remote post type endpoint.', 'distributor' ) );
- }
-
- $types_urls[ $post_type ] = $this->parse_type_items_link( $types_body_array[ $post_type ] );
-
- if ( empty( $types_urls[ $post_type ] ) ) {
- return new \WP_Error( 'no-pull-post-type', esc_html__( 'Could not determine remote post type endpoint.', 'distributor' ) );
- }
- }
-
$args_str = '';
if ( ! empty( $posts_per_page ) ) {
From c8a11e7fb85162ab9e6b68536b206a898922e616 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:01:36 +1000
Subject: [PATCH 41/57] Use POST request for pulling single post.
---
.../WordPressExternalConnection.php | 148 +-----------------
1 file changed, 8 insertions(+), 140 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index f8622c751..aff4b141a 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -186,152 +186,20 @@ public function remote_get( $args = array() ) {
$args_str .= 'per_page=' . (int) $posts_per_page;
}
- /**
- * Filter the remote_get query arguments
- *
- * @since 1.0
- * @hook dt_remote_get_query_args
- *
- * @param {array} $query_args The existing query arguments.
- * @param {array} $args The arguments originally passed to `remote_get`.
- * @param {object} $this The authentication class.
- *
- * @return {array} The existing query arguments.
- */
- $query_args = apply_filters( 'dt_remote_get_query_args', $query_args, $args, $this );
-
- foreach ( $query_args as $arg_key => $arg_value ) {
- if ( is_array( $arg_value ) ) {
- foreach ( $arg_value as $arg_value_value ) {
- if ( ! empty( $args_str ) ) {
- $args_str .= '&';
- }
-
- $args_str .= $arg_key . '[]=' . $arg_value_value;
- }
- } else {
- if ( ! empty( $args_str ) ) {
- $args_str .= '&';
- }
-
- $args_str .= $arg_key . '=' . $arg_value;
- }
- }
-
- $context = 'view';
-
- $prelim_get_args = $this->auth_handler->format_get_args();
-
- /**
- * See if we are trying to authenticate
- */
- if ( ! empty( $prelim_get_args ) && ! empty( $prelim_get_args['headers'] ) && ! empty( $prelim_get_args['headers']['Authorization'] ) ) {
- $context = 'edit';
-
- if ( ! empty( $args_str ) ) {
- $args_str .= '&';
- }
-
- $args_str .= 'context=edit';
- }
-
- if ( ! empty( $id ) ) {
- $query_args = array(
- 'include' => (int) $id,
- 'post_type' => isset( $args['post_type'] ) ? $args['post_type'] : 'any',
- );
- $posts_response = $this->remote_post(
- untrailingslashit( $this->base_url ) . '/' . self::$namespace . '/distributor/list-pull-content',
- $query_args
- );
-
- if ( is_wp_error( $posts_response ) ) {
- return $posts_response;
- }
-
- return $posts_response['items'][0];
- } else {
- $posts_url = untrailingslashit( $types_urls[ $post_type ] ) . '/?' . $args_str;
- }
-
- // Add request parameter to specify Distributor request
- $posts_url = add_query_arg( 'distributor_request', '1', $posts_url );
-
- $posts_response = Utils\remote_http_request(
- /**
- * Filter the URL that remote_get will use
- *
- * @since 1.0
- * @hook dt_remote_get_url
- *
- * @param {string} $posts_url The posts URL
- * @param {string} $args The arguments originally passed to `remote_get`.
- * @param {object} $this The authentication class.
- *
- * @return {string} The posts URL.
- */
- apply_filters( 'dt_remote_get_url', $posts_url, $args, $this ),
- // phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout -- false positive, shorter on VIP.
- $this->auth_handler->format_get_args( array( 'timeout' => 45 ) )
+ $query_args = array(
+ 'include' => (int) $id,
+ 'post_type' => isset( $args['post_type'] ) ? $args['post_type'] : 'any',
+ );
+ $posts_response = $this->remote_post(
+ untrailingslashit( $this->base_url ) . '/wp/v2/distributor/list-pull-content',
+ $query_args
);
if ( is_wp_error( $posts_response ) ) {
return $posts_response;
}
- $response_code = wp_remote_retrieve_response_code( $posts_response );
-
- if ( 200 !== $response_code ) {
-
- if ( 404 === $response_code ) {
- return new \WP_Error( 'bad-endpoint', esc_html__( 'Could not connect to API endpoint.', 'distributor' ) );
- }
-
- $posts_body = json_decode( wp_remote_retrieve_body( $posts_response ), true );
-
- $code = empty( $posts_body['code'] ) ? 'endpoint-error' : esc_html( $posts_body['code'] );
- $message = empty( $posts_body['message'] ) ? esc_html__( 'API endpoint error.', 'distributor' ) : esc_html( $posts_body['message'] );
-
- return new \WP_Error( $code, $message );
- }
-
- $posts_body = wp_remote_retrieve_body( $posts_response );
-
- if ( empty( $posts_body ) ) {
- return new \WP_Error( 'no-response-body', esc_html__( 'Response body is empty.', 'distributor' ) );
- }
-
- $posts = json_decode( $posts_body, true );
- $formatted_posts = array();
-
- $response_headers = wp_remote_retrieve_headers( $posts_response );
-
- if ( empty( $id ) ) {
- foreach ( $posts as $post ) {
- $post['full_connection'] = ( ! empty( $response_headers['X-Distributor'] ) );
-
- $formatted_posts[] = $this->to_wp_post( $post );
- }
-
- $total_posts = wp_remote_retrieve_header( $posts_response, 'X-WP-Total' );
- if ( empty( $total_posts ) ) {
- $total_posts = count( $formatted_posts );
- }
-
- // Filter documented above.
- return apply_filters(
- 'dt_remote_get',
- [
- 'items' => $formatted_posts,
- 'total_items' => $total_posts,
- ],
- $args,
- $this
- );
- } else {
- // Filter documented above.
- return apply_filters( 'dt_remote_get', $this->to_wp_post( $posts ), $args, $this );
- }
+ return $posts_response['items'][0];
}
/**
From ba2c9074525fcabf608751bcd717d88efcbce400 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:02:47 +1000
Subject: [PATCH 42/57] Remove duplicate wp_remote_retrieve_headers mock.
---
tests/php/includes/common.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tests/php/includes/common.php b/tests/php/includes/common.php
index 6a4a21f40..3eb11a602 100644
--- a/tests/php/includes/common.php
+++ b/tests/php/includes/common.php
@@ -195,10 +195,8 @@ function remote_get_setup() {
);
\WP_Mock::userFunction(
- 'wp_remote_retrieve_headers', [
- 'return' => [
- 'X-Distributor' => 'yes',
- ],
+ 'wp_remote_request', [
+ 'return' => new stdClass(),
]
);
From 24834904a2de50ae950ed324a7e73d36e199155b Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:03:18 +1000
Subject: [PATCH 43/57] Add wp_remote_retrieve_headers mock to pull test.
---
tests/php/WordPressExternalConnectionTest.php | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/php/WordPressExternalConnectionTest.php b/tests/php/WordPressExternalConnectionTest.php
index 299ba2b47..9d4dea74e 100644
--- a/tests/php/WordPressExternalConnectionTest.php
+++ b/tests/php/WordPressExternalConnectionTest.php
@@ -267,6 +267,14 @@ public function test_pull() {
\WP_Mock::userFunction( 'get_current_user_id' );
\WP_Mock::userFunction( 'delete_post_meta' );
+ \WP_Mock::userFunction(
+ 'wp_remote_retrieve_headers', [
+ 'return' => [
+ 'X-Distributor' => 'yes',
+ ],
+ ]
+ );
+
\WP_Mock::userFunction(
'wp_insert_post', [
'return' => 2,
From bc5772d824b94277b5550cbccfcfa8076da1f47b Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:03:43 +1000
Subject: [PATCH 44/57] Modify mocks for new flow wrapping post requests.
---
tests/php/WordPressExternalConnectionTest.php | 20 ++++++-------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/tests/php/WordPressExternalConnectionTest.php b/tests/php/WordPressExternalConnectionTest.php
index 9d4dea74e..6c8b587fa 100644
--- a/tests/php/WordPressExternalConnectionTest.php
+++ b/tests/php/WordPressExternalConnectionTest.php
@@ -321,7 +321,6 @@ public function test_remote_get() {
\WP_Mock::userFunction(
'wp_remote_retrieve_response_code', [
- 'times' => 2,
'return' => 200,
]
);
@@ -335,12 +334,6 @@ public function test_remote_get() {
]
);
- \WP_Mock::userFunction(
- 'add_query_arg', [
- 'times' => 1,
- ]
- );
-
\WP_Mock::userFunction(
'post_type_exists', [
'args' => [ '' ],
@@ -362,15 +355,14 @@ public function test_remote_get() {
]
);
- $this->assertInstanceOf(
- \WP_Post::class, $this->connection->remote_get(
- [
- 'id' => 111,
- 'post_type' => 'post',
- ]
- )
+ $actual = $this->connection->remote_get(
+ [
+ 'id' => 111,
+ 'post_type' => 'post',
+ ]
);
+ $this->assertInstanceOf( \WP_Post::class, $actual );
}
/**
From e0f4d31af526ed27a043623e5b3282588a270dec Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:13:07 +1000
Subject: [PATCH 45/57] Remove unused variable.
---
.../ExternalConnections/WordPressExternalConnection.php | 6 ------
1 file changed, 6 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index aff4b141a..64812e294 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -180,12 +180,6 @@ public function remote_get( $args = array() ) {
return $posts_response;
}
- $args_str = '';
-
- if ( ! empty( $posts_per_page ) ) {
- $args_str .= 'per_page=' . (int) $posts_per_page;
- }
-
$query_args = array(
'include' => (int) $id,
'post_type' => isset( $args['post_type'] ) ? $args['post_type'] : 'any',
From 0df5b63291697324184bc20334657331f4666ff0 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Tue, 18 Apr 2023 16:37:05 +1000
Subject: [PATCH 46/57] Use reset rather than zero as list_filter maintains
key.
---
.../classes/ExternalConnections/WordPressExternalConnection.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 64812e294..2ab09e775 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -344,7 +344,7 @@ public function pull( $items ) {
$created_posts[] = new \WP_Error( 'no-post', esc_html__( 'No post found.', 'distributor' ) );
continue;
}
- $post = $post[0];
+ $post = reset( $post );
$post_props = get_object_vars( $post );
$post_array = array();
From e7cbbc3d4376e45324d2af014ad207e240903fd2 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 19 Apr 2023 12:12:59 +1000
Subject: [PATCH 47/57] Correct site meta source data.
---
.../ExternalConnections/WordPressExternalConnection.php | 4 ++--
tests/php/includes/common.php | 8 +++++++-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 2ab09e775..ea1755837 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -395,8 +395,8 @@ public function pull( $items ) {
update_post_meta( $new_post, 'dt_original_source_id', (int) $this->id );
update_post_meta( $new_post, 'dt_syndicate_time', time() );
update_post_meta( $new_post, 'dt_original_post_url', esc_url_raw( $post_array['link'] ) );
- update_post_meta( $new_post, 'dt_original_site_name', sanitize_text_field( $post_array['distributor_original_site_name'] ) );
- update_post_meta( $new_post, 'dt_original_site_url', sanitize_text_field( $post_array['distributor_original_site_url'] ) );
+ update_post_meta( $new_post, 'dt_original_site_name', sanitize_text_field( $post_array['original_site_name'] ) );
+ update_post_meta( $new_post, 'dt_original_site_url', sanitize_text_field( $post_array['original_site_url'] ) );
if ( ! empty( $post->post_parent ) ) {
update_post_meta( $new_post, 'dt_original_post_parent', (int) $post->post_parent );
diff --git a/tests/php/includes/common.php b/tests/php/includes/common.php
index 3eb11a602..84deb0257 100644
--- a/tests/php/includes/common.php
+++ b/tests/php/includes/common.php
@@ -188,6 +188,12 @@ function remote_get_setup() {
],
];
+ $post_response = $rest_response[0];
+ $post_response['original_site_name'] = $post_response['distributor_original_site_name'];
+ $post_response['original_site_url'] = $post_response['distributor_original_site_url'];
+ unset( $post_response['distributor_original_site_name'] );
+ unset( $post_response['distributor_original_site_url'] );
+
\WP_Mock::userFunction(
'wp_remote_post', [
'return' => new stdClass(),
@@ -214,7 +220,7 @@ function remote_get_setup() {
\WP_Mock::userFunction(
'wp_list_filter', [
- 'return' => [ new WP_Post( (object) $rest_response[0] ) ],
+ 'return' => [ new WP_Post( (object) $post_response ) ],
]
);
}
From fa682463d32dc39877898af0270c75a6853f1f36 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 26 Apr 2023 10:35:22 +1000
Subject: [PATCH 48/57] Sanitize and slash post meta as appropriate.
---
.../classes/InternalConnections/NetworkSiteConnection.php | 6 +++---
phpcs.xml | 5 ++++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index 5a25d406b..25f67a617 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -301,9 +301,9 @@ public function pull( $items ) {
if ( ! is_wp_error( $new_post_id ) ) {
update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $this->site->blog_id );
- update_post_meta( $new_post_id, 'dt_syndicate_time', time() );
- update_post_meta( $new_post_id, 'dt_original_post_id', $new_post_args['meta_input']['dt_original_post_id'] );
- update_post_meta( $new_post_id, 'dt_original_post_url', $new_post_args['meta_input']['dt_original_post_url'] );
+ update_post_meta( $new_post_id, 'dt_syndicate_time', (int) time() );
+ update_post_meta( $new_post_id, 'dt_original_post_id', (int) $new_post_args['meta_input']['dt_original_post_id'] );
+ update_post_meta( $new_post_id, 'dt_original_post_url', wp_slash( sanitize_url( $new_post_args['meta_input']['dt_original_post_url'] ) ) );
/**
* Allow bypassing of all meta processing.
diff --git a/phpcs.xml b/phpcs.xml
index 3288dc58d..df4ee2967 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,6 +1,9 @@
-
+
+
+
+
From 9dd57461fd98b2067c5f3e5ea051f9180edb6b24 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 26 Apr 2023 10:37:39 +1000
Subject: [PATCH 49/57] Replace placeholder versions with 2.0.0.
---
includes/rest-api.php | 8 ++++----
includes/utils.php | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index d371f6b97..ebc628b0f 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -161,7 +161,7 @@ function register_rest_routes() {
/**
* Set the accepted arguments for the pull content list endpoint.
*
- * @since x.x.x Introduced the include, order and orderby arguments.
+ * @since 2.0.0 Introduced the include, order and orderby arguments.
*
* @return array
*/
@@ -612,7 +612,7 @@ function check_post_types_permissions() {
/**
* Get a list of content to show on the Pull screen
*
- * @since x.x.x Renamed from get_pull_content() to get_pull_content_list().
+ * @since 2.0.0 Renamed from get_pull_content() to get_pull_content_list().
*
* @param \WP_Rest_Request $request API request arguments
* @return \WP_REST_Response|\WP_Error
@@ -725,13 +725,13 @@ function get_pull_content_list( $request ) {
/**
* Get a list of content to show on the Pull screen
*
- * @since x.x.x Deprecated in favour of get_pull_content_list().
+ * @since 2.0.0 Deprecated in favour of get_pull_content_list().
*
* @param array ...$args Arguments.
* @return \WP_REST_Response|\WP_Error
*/
function get_pull_content( ...$args ) {
- _deprecated_function( __FUNCTION__, 'x.x.x', __NAMESPACE__ . '\\get_pull_content_list' );
+ _deprecated_function( __FUNCTION__, '2.0.0', __NAMESPACE__ . '\\get_pull_content_list' );
return get_pull_content_list( ...$args );
}
diff --git a/includes/utils.php b/includes/utils.php
index d51dc05a3..c483a766c 100644
--- a/includes/utils.php
+++ b/includes/utils.php
@@ -12,7 +12,7 @@
/**
* Determine if this is a development install of Distributor.
*
- * @since x.x.x
+ * @since 2.0.0
*
* @return bool True if this is a development install, false otherwise.
*/
From 827d4d6d50b2be47636e2b990198730dcf1c7a1d Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 26 Apr 2023 10:41:14 +1000
Subject: [PATCH 50/57] Fix post status argument sanitization.
---
includes/rest-api.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index ebc628b0f..94a93a66b 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -307,13 +307,13 @@ function( $post_type ) {
}
/*
- * Only show post statuses viewable post statues.
+ * Only show viewable post statues.
*
- * `is_post_type_viewable()` is used to filter the results as
+ * `is_post_status_viewable()` is used to filter the results as
* WordPress applies a complex set of rules to determine if a post
* status is viewable.
*/
- $allowed_statues = array_keys( array_filter( get_post_stati(), 'is_post_type_viewable' ) );
+ $allowed_statues = array_keys( array_filter( get_post_stati(), 'is_post_status_viewable' ) );
if ( in_array( 'any', $param, true ) ) {
return $allowed_statues;
From e747fb664af4d1e3b1fff4a0ba63b68d0b2353b0 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Wed, 26 Apr 2023 10:45:28 +1000
Subject: [PATCH 51/57] Mock sanitize_url() as passthrough function.
---
tests/php/NetworkSiteConnectionsTest.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/php/NetworkSiteConnectionsTest.php b/tests/php/NetworkSiteConnectionsTest.php
index 85f3b61c9..6cef652c8 100644
--- a/tests/php/NetworkSiteConnectionsTest.php
+++ b/tests/php/NetworkSiteConnectionsTest.php
@@ -265,6 +265,7 @@ public function test_pull() {
\WP_Mock::userFunction( 'get_current_blog_id' );
\WP_Mock::userFunction( 'remove_filter' );
\WP_Mock::passthruFunction( 'wp_slash' );
+ \WP_Mock::passthruFunction( 'sanitize_url' );
\WP_Mock::userFunction(
'get_post', [
From 27b729cb54299bb79cf0b9ab192631d696070f0d Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 28 Apr 2023 10:18:08 +1000
Subject: [PATCH 52/57] Use absint for positive integers.
---
.../WordPressExternalConnection.php | 2 +-
.../InternalConnections/NetworkSiteConnection.php | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index ea1755837..7815c6b60 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -181,7 +181,7 @@ public function remote_get( $args = array() ) {
}
$query_args = array(
- 'include' => (int) $id,
+ 'include' => absint( $id ),
'post_type' => isset( $args['post_type'] ) ? $args['post_type'] : 'any',
);
$posts_response = $this->remote_post(
diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php
index 25f67a617..7a9861636 100644
--- a/includes/classes/InternalConnections/NetworkSiteConnection.php
+++ b/includes/classes/InternalConnections/NetworkSiteConnection.php
@@ -161,8 +161,8 @@ public function push( $post, $args = array() ) {
$output['id'] = $new_post_id;
- update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $original_blog_id );
- update_post_meta( $new_post_id, 'dt_syndicate_time', time() );
+ update_post_meta( $new_post_id, 'dt_original_blog_id', absint( $original_blog_id ) );
+ update_post_meta( $new_post_id, 'dt_syndicate_time', absint( time() ) );
/**
* Allow bypassing of all meta processing.
@@ -300,9 +300,9 @@ public function pull( $items ) {
remove_filter( 'wp_insert_post_data', array( '\Distributor\InternalConnections\NetworkSiteConnection', 'maybe_set_modified_date' ), 10, 2 );
if ( ! is_wp_error( $new_post_id ) ) {
- update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $this->site->blog_id );
- update_post_meta( $new_post_id, 'dt_syndicate_time', (int) time() );
- update_post_meta( $new_post_id, 'dt_original_post_id', (int) $new_post_args['meta_input']['dt_original_post_id'] );
+ update_post_meta( $new_post_id, 'dt_original_blog_id', absint( $this->site->blog_id ) );
+ update_post_meta( $new_post_id, 'dt_syndicate_time', absint( time() ) );
+ update_post_meta( $new_post_id, 'dt_original_post_id', absint( $new_post_args['meta_input']['dt_original_post_id'] ) );
update_post_meta( $new_post_id, 'dt_original_post_url', wp_slash( sanitize_url( $new_post_args['meta_input']['dt_original_post_url'] ) ) );
/**
From 62d165fe17ce35010d197ebdd4e076800f96a311 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 28 Apr 2023 10:20:54 +1000
Subject: [PATCH 53/57] Escape `\` in callback.
---
includes/rest-api.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index 94a93a66b..c83cf08de 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -151,7 +151,7 @@ function register_rest_routes() {
'distributor/list-pull-content',
array(
'methods' => 'POST',
- 'callback' => __NAMESPACE__ . '\get_pull_content_list',
+ 'callback' => __NAMESPACE__ . '\\get_pull_content_list',
'permission_callback' => __NAMESPACE__ . '\\get_pull_content_permissions',
'args' => get_pull_content_list_args(),
)
From 0efefdad961cb60de88776c43af3046c81065362 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 28 Apr 2023 10:22:58 +1000
Subject: [PATCH 54/57] Remove duplicate `validate_callback` entry.
---
includes/rest-api.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/includes/rest-api.php b/includes/rest-api.php
index c83cf08de..2445df0a5 100644
--- a/includes/rest-api.php
+++ b/includes/rest-api.php
@@ -274,7 +274,6 @@ function( $post_type ) {
return $param;
},
- 'validate_callback' => 'rest_validate_request_arg',
),
'search' => array(
'description' => esc_html__( 'Limit results to those matching a string.', 'distributor' ),
From 671837f4e402c9457710c9b6a20e6a20b1598f43 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 28 Apr 2023 10:29:16 +1000
Subject: [PATCH 55/57] Add since tag annotation.
---
includes/classes/DistributorPost.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/includes/classes/DistributorPost.php b/includes/classes/DistributorPost.php
index d0cc43050..73278d7a8 100644
--- a/includes/classes/DistributorPost.php
+++ b/includes/classes/DistributorPost.php
@@ -823,6 +823,8 @@ protected function to_insert( $args = array() ) {
* This is a wrapper for the ::to_insert() method that includes extra
* data required for the pull screen.
*
+ * @since 2.0.0
+ *
* @param mixed $args {
* Optional. Array of push arguments
* @see ::to_insert() for arguments.
From 18eb1e4ca46abff50195e5cc748de3152dbde716 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Fri, 28 Apr 2023 10:39:52 +1000
Subject: [PATCH 56/57] Reproduce absint 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 84deb0257..e5100d37d 100644
--- a/tests/php/includes/common.php
+++ b/tests/php/includes/common.php
@@ -296,6 +296,20 @@ function wp_parse_args( $settings, $defaults ) {
return array_merge( $defaults, $settings );
}
+/**
+ * Mock absint() function.
+ *
+ * Copied from WordPress core.
+ *
+ * @since 2.0.0
+ *
+ * @param mixed $maybeint Data you wish to have converted to a non-negative integer.
+ * @return int A non-negative integer.
+ */
+function absint( $maybeint ) {
+ return abs( (int) $maybeint );
+}
+
/**
* Stub for remove_filter to avoid failure in test_remote_get()
*
From c83fde14ce73b81556adf6cd4f77ce0c63737fd1 Mon Sep 17 00:00:00 2001
From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Date: Thu, 25 May 2023 13:53:41 +1000
Subject: [PATCH 57/57] Version check external version of Distributor on pull
screen.
---
.../WordPressExternalConnection.php | 20 +++++++++++++++++
includes/pull-ui.php | 22 ++++++++++---------
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php
index 7815c6b60..01c5d9389 100644
--- a/includes/classes/ExternalConnections/WordPressExternalConnection.php
+++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php
@@ -271,6 +271,26 @@ public function remote_post( $url = '', $args = array() ) {
return new \WP_Error( 'no-response-body', esc_html__( 'Response body is empty.', 'distributor' ) );
}
+ if (
+ false === Utils\is_development_version()
+ && isset( $response_headers['x-distributor'] )
+ && (
+ ! isset( $response_headers['x-distributor-version'] )
+ || version_compare( $response_headers['x-distributor-version'], '2.0.0', '<' )
+ )
+ ) {
+ $version_error = new \WP_Error();
+ $version_error->add(
+ 'old-distributor-version',
+ esc_html__( 'Pulling content from external connections requires Distributor version 2.0.0 or later.', 'distributor' )
+ );
+ $version_error->add(
+ 'old-distributor-version',
+ esc_html__( 'Please update Distributor on the site you are pulling content from.', 'distributor' )
+ );
+ return $version_error;
+ }
+
$posts = json_decode( $posts_body, true );
$formatted_posts = array();
diff --git a/includes/pull-ui.php b/includes/pull-ui.php
index 14226b813..f56c02a73 100644
--- a/includes/pull-ui.php
+++ b/includes/pull-ui.php
@@ -529,16 +529,18 @@ function dashboard() {
prepare_items(); ?>
pull_error ) ) : ?>
-
-
- pull_error as $error ) : ?>
- -
-
-
-
-
+
+
+
+ pull_error as $error ) : ?>
+ -
+
+
+
+
+
views(); ?>