summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.php177
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' );