diff options
Diffstat (limited to 'plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-publicize-share-post.php')
-rw-r--r-- | plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-publicize-share-post.php | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-publicize-share-post.php b/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-publicize-share-post.php new file mode 100644 index 00000000..35c82a55 --- /dev/null +++ b/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-publicize-share-post.php @@ -0,0 +1,177 @@ +<?php +/** + * Publicize: Share post + * + * This file is synced from the Jetpack monorepo to WPCOM. + * + * @package automattic/jetpack + * @since + */ + +use Automattic\Jetpack\Connection\Client; + +require_once __DIR__ . '/publicize-connections.php'; + +/** + * Publicize: Share post class. + */ +class WPCOM_REST_API_V2_Endpoint_Publicize_Share_Post extends WP_REST_Controller { + /** + * The constructor sets the route namespace, rest_base, and registers our API route and endpoint. + * Additionally, we check if we're executing this file on WPCOM or Jetpack. + */ + public function __construct() { + $this->namespace = 'wpcom/v2'; + + // $wpcom_is_wpcom_only_endpoint = true keeps WPCOM from trying to loop back to the Jetpack endpoint. + $this->wpcom_is_wpcom_only_endpoint = true; + + // Determine if this endpoint is running on WPCOM or not. + $this->is_wpcom = false; + if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { + $this->is_wpcom = true; + } + + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); + } + + /** + * This file is synced from Jetpack to WPCOM and this method creates a slightly different route for both sites. + * Jetpack route: http://{$site}/wp-json/wpcom/v2/posts/{$postId}/publicize + * WPCOM route: https://public-api.wordpress.com/wpcom/v2/sites/{$siteId}/posts/{$postId}/publicize + */ + public function register_routes() { + register_rest_route( + $this->namespace, + '/posts/(?P<postId>\d+)/publicize', + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'share_post' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => array( + 'message' => array( + 'description' => __( 'The message to share.', 'jetpack' ), + 'type' => 'string', + 'required' => true, + 'validate_callback' => function ( $param ) { + return is_string( $param ); + }, + 'sanitize_callback' => 'sanitize_textarea_field', + ), + 'skipped_connections' => array( + 'description' => __( 'Array of external connection IDs to skip sharing.', 'jetpack' ), + 'type' => 'array', + 'required' => false, + 'validate_callback' => function ( $param ) { + return is_array( $param ); + }, + 'sanitize_callback' => function ( $param ) { + return array_map( 'absint', $param ); + }, + ), + ), + ), + // override = true because this API route was commandeered from the file + // wp-content/rest-api-plugins/endpoints/sites-publicize.php on WPCOM. + true + ); + } + + /** + * Ensure the user has proper tokens and permissions to publish posts on this blog. + * + * @return WP_Error|boolean + */ + public function permissions_check() { + if ( ! get_current_user_id() ) { + return new WP_Error( + 'rest_cannot_view', + __( 'Sorry, you cannot view this resource without a valid token for this blog.', 'jetpack' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + if ( ! current_user_can( 'publish_posts' ) ) { + return new WP_Error( 'unauthorized', 'Your token must have permission to publish posts.', array( 'status' => 401 ) ); + } + return true; + } + + /** + * If this method callback is executed on WPCOM, we share the post using republicize_post(). If this method callback + * is executed on a Jetpack site, we make an API call to WPCOM using wpcom_json_api_request_as_user() and return + * the results. In both cases, this file and method are executed, as this file is synced from Jetpack to WPCOM. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|array The publicize results, including two arrays: `results` and `errors` + */ + public function share_post( $request ) { + $post_id = $request->get_param( 'postId' ); + $message = trim( $request->get_param( 'message' ) ); + $skip_connection_ids = $request->get_param( 'skipped_connections' ); + + if ( $this->is_wpcom ) { + $post = get_post( $post_id ); + + if ( empty( $post ) ) { + return new WP_Error( 'not_found', 'Cannot find that post', array( 'status' => 404 ) ); + } + if ( 'publish' !== $post->post_status ) { + return new WP_Error( 'not_published', 'Cannot publicize an unpublished post', array( 'status' => 400 ) ); + } + + $publicize = publicize_init(); + $result = $publicize->republicize_post( (int) $post_id, $message, $skip_connection_ids, true ); + if ( false === $result ) { + return new WP_Error( 'not_found', 'Cannot find that post', array( 'status' => 404 ) ); + } + + return $result; + } else { + $response = $this->proxy_request( $post_id, $message, $skip_connection_ids ); + if ( is_wp_error( $response ) ) { + return rest_ensure_response( $response ); + } + + return json_decode( wp_remote_retrieve_body( $response ), true ); + } + } + + /** + * Passes the request on to the WPCOM endpoint, and returns the result. + * + * @param int $post_id The post ID being shared. + * @param string $message The custom message to be used. + * @param array $skip_connection_ids An array of connection IDs where the post shouldn't be shared. + * + * @return array|WP_Error $response Response data, else WP_Error on failure. + */ + public function proxy_request( $post_id, $message, $skip_connection_ids ) { + /* + * Publicize endpoint on WPCOM: + * [POST] wpcom/v2/sites/{$siteId}/posts/{$postId}/publicize + * body: + * - message: string + * - skipped_connections: array of connection ids to skip + */ + $url = sprintf( + '/sites/%d/posts/%d/publicize', + Jetpack_Options::get_option( 'id' ), + $post_id + ); + + return Client::wpcom_json_api_request_as_user( + $url, + 'v2', + array( + 'method' => 'POST', + ), + array( + 'message' => $message, + 'skipped_connections' => $skip_connection_ids, + ) + ); + + } +} + +wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Publicize_Share_Post' ); |