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/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; } 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/classes/DistributorPost.php b/includes/classes/DistributorPost.php index e1e1400d3..73278d7a8 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,40 @@ 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. + * + * @since 2.0.0 + * + * @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['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; + $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; + } + /** * Get the post data in a format suitable for the distributor REST API endpoint. * diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php index 9cecedf6c..01c5d9389 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 ) ) { $query_args['post_type'] = isset( $post_type ) ? $post_type : 'post'; $query_args['posts_per_page'] = isset( $posts_per_page ) ? $posts_per_page : 20; @@ -180,193 +180,20 @@ 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 ) ) { - $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 ) ) { - $posts_url = untrailingslashit( $types_urls[ $post_type ] ) . '/' . $id . '/?context=' . $context; - } 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' => absint( $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]; } /** @@ -444,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(); @@ -489,18 +336,35 @@ 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'] ); - if ( is_wp_error( $post ) ) { - $created_posts[] = $post; + // 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( $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 ) ) { + $created_posts[] = new \WP_Error( 'no-post', esc_html__( 'No post found.', 'distributor' ) ); continue; } + $post = reset( $post ); $post_props = get_object_vars( $post ); $post_array = array(); @@ -509,26 +373,24 @@ public function pull( $items ) { $post_array[ $key ] = $value; } + $update = false; + // 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'] ) ) { + $update = true; $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. * @@ -543,7 +405,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 ); @@ -940,55 +806,18 @@ private function not_distributor_internal_post_type( $post_type ) { * @return \WP_Post */ private function to_wp_post( $post ) { - $obj = new \stdClass(); - - $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 = (object) $post; - $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 +830,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; } /** diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php index 857eb9a95..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. @@ -256,15 +256,25 @@ 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_array = array(); + $post_props = $post; + $post_array = $post_props; $current_blog_id = get_current_blog_id(); if ( ! empty( $post_props['meta']['dt_connection_map'] ) ) { @@ -278,41 +288,22 @@ 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 ); - } + 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'] ) ) ); /** * Allow bypassing of all meta processing. @@ -321,15 +312,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 +330,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 +348,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 +495,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 +591,10 @@ 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 ); + // 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(); 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 ) ) : ?> -
-