summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/json-endpoints')
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-autosave-post-v1-1-endpoint.php5
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-bulk-delete-post-endpoint.php3
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-edit-media-v1-2-endpoint.php252
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-comment-counts-endpoint.php16
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-media-v1-2-endpoint.php11
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php59
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-endpoint.php3
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-2-endpoint.php4
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php28
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php5
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-roles-endpoint.php71
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php12
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php78
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php1
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php24
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php8
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-upload-media-v1-1-endpoint.php4
-rw-r--r--plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-sync-endpoint.php1
-rw-r--r--plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-user-connect-endpoint.php1
-rw-r--r--plugins/jetpack/json-endpoints/jetpack/json-api-jetpack-endpoints.php3
24 files changed, 501 insertions, 112 deletions
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-autosave-post-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-autosave-post-v1-1-endpoint.php
index 7747c214..452a7c25 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-autosave-post-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-autosave-post-v1-1-endpoint.php
@@ -58,6 +58,11 @@ class WPCOM_JSON_API_Autosave_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
}
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ // Make sure Custom Post Types, etc. get registered.
+ $this->load_theme_functions();
+ }
+
$post = get_post( $post_id );
if ( ! $post || is_wp_error( $post ) ) {
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-bulk-delete-post-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-bulk-delete-post-endpoint.php
index 34c0a23b..31ab8d95 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-bulk-delete-post-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-bulk-delete-post-endpoint.php
@@ -35,8 +35,7 @@ new WPCOM_JSON_API_Bulk_Delete_Post_Endpoint( array(
class WPCOM_JSON_API_Bulk_Delete_Post_Endpoint extends WPCOM_JSON_API_Update_Post_v1_1_Endpoint {
// /sites/%s/posts/delete
- // The unused $object parameter is for making the method signature compatible with its parent class method.
- function callback( $path = '', $blog_id = 0, $object = null ) {
+ function callback( $path = '', $blog_id = 0, $post_id = 0 ) {
$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
if ( is_wp_error( $blog_id ) ) {
return $blog_id;
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-edit-media-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-edit-media-v1-2-endpoint.php
index 368e4541..2366653d 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-edit-media-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-edit-media-v1-2-endpoint.php
@@ -2,6 +2,9 @@
jetpack_require_lib( 'class.media' );
+const REVISION_HISTORY_MAXIMUM_AMOUNT = 0;
+const WP_ATTACHMENT_IMAGE_ALT = '_wp_attachment_image_alt';
+
new WPCOM_JSON_API_Edit_Media_v1_2_Endpoint( array(
'description' => 'Edit a media item.',
'group' => 'media',
@@ -24,15 +27,15 @@ new WPCOM_JSON_API_Edit_Media_v1_2_Endpoint( array(
'artist' => "(string) Audio Only. Artist metadata for the audio track.",
'album' => "(string) Audio Only. Album metadata for the audio track.",
'media' => "(object) An object file to attach to the post. To upload media, " .
- "the entire request should be multipart/form-data encoded. " .
- "Multiple media items will be displayed in a gallery. Accepts " .
- "jpg, jpeg, png, gif, pdf, doc, ppt, odt, pptx, docx, pps, ppsx, xls, xlsx, key. " .
- "Audio and Video may also be available. See <code>allowed_file_types</code> " .
- "in the options response of the site endpoint. " .
- "<br /><br /><strong>Example</strong>:<br />" .
+ "the entire request should be multipart/form-data encoded. " .
+ "Multiple media items will be displayed in a gallery. Accepts " .
+ "jpg, jpeg, png, gif, pdf, doc, ppt, odt, pptx, docx, pps, ppsx, xls, xlsx, key. " .
+ "Audio and Video may also be available. See <code>allowed_file_types</code> " .
+ "in the options response of the site endpoint. " .
+ "<br /><br /><strong>Example</strong>:<br />" .
"<code>curl \<br />--form 'title=Image' \<br />--form 'media=@/path/to/file.jpg' \<br />-H 'Authorization: BEARER your-token' \<br />'https://public-api.wordpress.com/rest/v1/sites/123/posts/new'</code>",
'attrs' => "(object) An Object of attributes (`title`, `description` and `caption`) " .
- "are supported to assign to the media uploaded via the `media` or `media_url`",
+ "are supported to assign to the media uploaded via the `media` or `media_url`",
'media_url' => "(string) An URL of the image to attach to a post.",
),
@@ -58,9 +61,9 @@ new WPCOM_JSON_API_Edit_Media_v1_2_Endpoint( array(
'videopress_guid' => '(string) (Video only) VideoPress GUID of the video when uploaded on a blog with VideoPress',
'videopress_processing_done' => '(bool) (Video only) If the video is uploaded on a blog with VideoPress, this will return the status of processing on the video.',
'revision_history' => '(object) An object with `items` and `original` keys. ' .
- '`original` is an object with data about the original image. ' .
- '`items` is an array of snapshots of the previous images of this Media. ' .
- 'Each item has the `URL`, `file, `extension`, `date`, and `mime_type` fields.'
+ '`original` is an object with data about the original image. ' .
+ '`items` is an array of snapshots of the previous images of this Media. ' .
+ 'Each item has the `URL`, `file, `extension`, `date`, and `mime_type` fields.'
),
'example_request' => 'https://public-api.wordpress.com/rest/v1.2/sites/82974409/media/446',
@@ -76,12 +79,31 @@ new WPCOM_JSON_API_Edit_Media_v1_2_Endpoint( array(
class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Media_v1_1_Endpoint {
/**
+ * Return an array of mime_type items allowed when the media file is uploaded.
+ *
+ * @return {Array} mime_type array
+ */
+ static function get_allowed_mime_types( $default_mime_types ) {
+ return array_unique( array_merge( $default_mime_types, array(
+ 'application/msword', // .doc
+ 'application/vnd.ms-powerpoint', // .ppt, .pps
+ 'application/vnd.ms-excel', // .xls
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', // .ppsx
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
+ 'application/vnd.oasis.opendocument.text', // .odt
+ 'application/pdf', // .pdf
+ ) ) );
+ }
+
+ /**
* Update the media post grabbing the post values from
* the `attrs` parameter
*
* @param {Number} $media_id - post media ID
* @param {Object} $attrs - `attrs` parameter sent from the client in the request body
- * @return bool|WP_Error `WP_Error` on failure. `true` on success.
+ * @return
*/
private function update_by_attrs_parameter( $media_id, $attrs ) {
$insert = array();
@@ -103,14 +125,18 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
$insert['ID'] = $media_id;
$update_action = wp_update_post( (object) $insert );
if ( is_wp_error( $update_action ) ) {
- $update_action;
+ return $update_action;
}
}
// Attributes: Alt
if ( isset( $attrs['alt'] ) ) {
$alt = wp_strip_all_tags( $attrs['alt'], true );
- update_post_meta( $media_id, Jetpack_Media::$WP_ATTACHMENT_IMAGE_ALT, $alt );
+ $post_update_action = update_post_meta( $media_id, WP_ATTACHMENT_IMAGE_ALT, $alt );
+
+ if ( is_wp_error( $post_update_action ) ) {
+ return $post_update_action;
+ }
}
// Attributes: Artist, Album
@@ -126,11 +152,126 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
// Before updating metadata, ensure that the item is audio
$item = $this->get_media_item_v1_1( $media_id );
if ( 0 === strpos( $item->mime_type, 'audio/' ) ) {
- wp_update_attachment_metadata( $media_id, $id3_meta );
+ $update_action = wp_update_attachment_metadata( $media_id, $id3_meta );
+ if ( is_wp_error( $update_action ) ) {
+ return $update_action;
+ }
}
}
- return $update_action;
+ return $post_update_action;
+ }
+
+ /**
+ * Return an object to be used to store into the revision_history
+ *
+ * @param {Object} $media_item - media post object
+ * @return {Object} the snapshot object
+ */
+ private function get_snapshot( $media_item ) {
+ $current_file = get_attached_file( $media_item->ID );
+ $file_paths = pathinfo( $current_file );
+
+ $snapshot = array(
+ 'date' => (string) $this->format_date( $media_item->post_modified_gmt, $media_item->post_modified ),
+ 'URL' => (string) wp_get_attachment_url( $media_item->ID ),
+ 'file' => (string) $file_paths['basename'],
+ 'extension' => (string) $file_paths['extension'],
+ 'mime_type' => (string) $media_item->post_mime_type,
+ 'size' => (int) filesize( $current_file )
+ );
+
+ return (object) $snapshot;
+ }
+
+ /**
+ * Try to remove the temporal file from the given file array.
+ *
+ * @param {Array} $file_array - Array with data about the temporal file
+ * @return {Boolean} `true` if the file has been removed.
+ * `false` either the file doesn't exist or it couldn't be removed.
+ */
+ private function remove_tmp_file( $file_array ) {
+ if ( ! file_exists ( $file_array['tmp_name'] ) ) {
+ return false;
+ }
+ return @unlink( $file_array['tmp_name'] );
+ }
+
+ /**
+ * Save the given temporal file in a local folder.
+ *
+ * @param {Array} $file_array
+ * @param {Number} $media_id
+ * @return {Array|WP_Error} An array with information about the new file saved or a WP_Error is something went wrong.
+ */
+ private function save_temporary_file( $file_array, $media_id ) {
+ $tmp_filename = $file_array['tmp_name'];
+
+ if ( ! file_exists( $tmp_filename ) ) {
+ return new WP_Error( 'invalid_input', 'No media provided in input.' );
+ }
+
+ // add additional mime_types through of the `jetpack_supported_media_sideload_types` filter
+ $mime_type_static_filter = array(
+ 'WPCOM_JSON_API_Edit_Media_v1_2_Endpoint',
+ 'get_allowed_mime_types'
+ );
+
+ add_filter( 'jetpack_supported_media_sideload_types', $mime_type_static_filter );
+ if (
+ ! $this->is_file_supported_for_sideloading( $tmp_filename ) &&
+ ! file_is_displayable_image( $tmp_filename )
+ ) {
+ @unlink( $tmp_filename );
+ return new WP_Error( 'invalid_input', 'Invalid file type.', 403 );
+ }
+ remove_filter( 'jetpack_supported_media_sideload_types', $mime_type_static_filter );
+
+ // generate a new file name
+ $tmp_new_filename = Jetpack_Media::generate_new_filename( $media_id, $file_array[ 'name' ] );
+
+ // start to create the parameters to move the temporal file
+ $overrides = array( 'test_form' => false );
+
+ $time = $this->get_time_string_from_guid( $media_id );
+
+ $file_array['name'] = $tmp_new_filename;
+ $file = wp_handle_sideload( $file_array, $overrides, $time );
+
+ $this->remove_tmp_file( $file_array );
+
+ if ( isset( $file['error'] ) ) {
+ return new WP_Error( 'upload_error', $file['error'] );
+ }
+
+ return $file;
+ }
+
+ /**
+ * File urls use the post date to generate a folder path.
+ * Post dates can change, so we use the original date used in the guid
+ * url so edits can remain in the same folder. In the following function
+ * we capture a string in the format of `YYYY/MM` from the guid.
+ *
+ * For example with a guid of
+ * "http://test.files.wordpress.com/2016/10/test.png" the resulting string
+ * would be: "2016/10"
+ *
+ * @param $media_id
+ *
+ * @return string
+ */
+ private function get_time_string_from_guid( $media_id ) {
+ $time = date( "Y/m", strtotime( current_time( 'mysql' ) ) );
+ if ( $media = get_post( $media_id ) ) {
+ $pattern = '/\/(\d{4}\/\d{2})\//';
+ preg_match( $pattern, $media->guid, $matches );
+ if ( count( $matches ) > 1 ) {
+ $time = $matches[1];
+ }
+ }
+ return $time;
}
/**
@@ -152,7 +293,7 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
}
// save the remote image into a tmp file
- $tmp = download_url( $url );
+ $tmp = download_url( wpcom_get_private_file( $url ) );
if ( is_wp_error( $tmp ) ) {
return $tmp;
}
@@ -163,6 +304,25 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
);
}
+ /**
+ * Add a new item into revision_history array.
+ *
+ * @param {Object} $media_item - media post
+ * @param {file} $file - file recentrly added
+ * @param {Boolean} $has_original_media - condition is the original media has been already added
+ * @return {Boolean} `true` if the item has been added. Otherwise `false`.
+ */
+ private function register_revision( $media_item, $file, $has_original_media ) {
+ if (
+ is_wp_error( $file ) ||
+ ! $has_original_media
+ ) {
+ return false;
+ }
+
+ add_post_meta( $media_item->ID, Jetpack_Media::$WP_REVISION_HISTORY, $this->get_snapshot( $media_item ) );
+ }
+
function callback( $path = '', $blog_id = 0, $media_id = 0 ) {
$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
if ( is_wp_error( $blog_id ) ) {
@@ -171,7 +331,7 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
$media_item = get_post( $media_id );
- if ( ! $media_item ) {
+ if ( ! $media_item || is_wp_error( $media_item ) ) {
return new WP_Error( 'unknown_media', 'Unknown Media', 404 );
}
@@ -186,36 +346,70 @@ class WPCOM_JSON_API_Edit_Media_v1_2_Endpoint extends WPCOM_JSON_API_Update_Medi
$input = $this->input( true );
// images
+ $media_file = $input['media'] ? (array) $input['media'] : null;
$media_url = $input['media_url'];
$media_attrs = $input['attrs'] ? (array) $input['attrs'] : null;
- if ( isset( $media_url ) ) {
+ if ( isset( $media_url ) || $media_file ) {
$user_can_upload_files = current_user_can( 'upload_files' ) || $this->api->is_authorized_with_upload_token();
if ( ! $user_can_upload_files ) {
return new WP_Error( 'unauthorized', 'User cannot upload media.', 403 );
}
- // save the temporal file locally
- $temporal_file = $this->build_file_array_from_url( $media_id, $media_url );
+ $has_original_media = Jetpack_Media::get_original_media( $media_id );
+
+ if ( ! $has_original_media ) {
+ // The first time that the media is updated
+ // the original media is stored into the revision_history
+ $snapshot = $this->get_snapshot( $media_item );
+ add_post_meta( $media_id, Jetpack_Media::$WP_ORIGINAL_MEDIA, $snapshot, true );
+ }
+
+ // save the temporal file locally
+ $temporal_file = $media_file ? $media_file : $this->build_file_array_from_url( $media_id, $media_url );
+
+ if ( is_wp_error( $temporal_file ) ) {
+ return $temporal_file;
+ }
- $edited_media_item = Jetpack_Media::edit_media_file( $media_id, $temporal_file );
+ $uploaded_file = $this->save_temporary_file( $temporal_file, $media_id );
- if ( is_wp_error( $edited_media_item ) ) {
- return $edited_media_item;
+ if ( is_wp_error( $uploaded_file ) ) {
+ return $uploaded_file;
+ }
+
+ // revision_history control
+ $this->register_revision( $media_item, $uploaded_file, $has_original_media );
+
+ $uploaded_path = $uploaded_file['file'];
+ $udpated_mime_type = $uploaded_file['type'];
+ $was_updated = update_attached_file( $media_id, $uploaded_path );
+
+ if ( $was_updated ) {
+ $new_metadata = wp_generate_attachment_metadata( $media_id, $uploaded_path );
+ wp_update_attachment_metadata( $media_id, $new_metadata );
+
+ // check maximum amount of revision_history
+ Jetpack_Media::limit_revision_history( $media_id, REVISION_HISTORY_MAXIMUM_AMOUNT );
+
+ wp_update_post( (object) array(
+ 'ID' => $media_id,
+ 'post_mime_type' => $udpated_mime_type
+ ) );
}
unset( $input['media'] );
unset( $input['media_url'] );
unset( $input['attrs'] );
+ }
- // update media through of `attrs` value it it's defined
- if ( $media_attrs ) {
- $updated_by_attrs = $this->update_by_attrs_parameter( $media_id, $media_attrs );
+ // update media through of `attrs` value it it's defined
+ if ( ( $media_file || isset( $media_url ) ) && $media_attrs ) {
+ $was_updated = $this->update_by_attrs_parameter( $media_id, $media_attrs );
- if ( is_wp_error( $updated_by_attrs ) ) {
- return $updated_by_attrs;
- }
+ if ( is_wp_error( $was_updated ) ) {
+ return $was_updated;
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-comment-counts-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-comment-counts-endpoint.php
index a86f2e8d..88688e42 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-comment-counts-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-comment-counts-endpoint.php
@@ -17,15 +17,13 @@ new WPCOM_JSON_API_GET_Comment_Counts_Endpoint( array(
'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/comment-counts',
'response_format' => array(
- 'comment_counts' => array(
- 'all' => '(int) Combined number of approved and unapproved comments',
- 'approved' => '(int) Number of approved comments',
- 'pending' => '(int) Number of unapproved comments',
- 'trash' => '(int) Number of trash comments',
- 'spam' => '(int) Number of spam comments',
- 'post_trashed' => '(int) Number of comments whose parent post has been trashed',
- 'total_comments' => '(int) Combined number of comments in each category',
- )
+ 'all' => '(int) Combined number of approved and unapproved comments',
+ 'approved' => '(int) Number of approved comments',
+ 'pending' => '(int) Number of unapproved comments',
+ 'trash' => '(int) Number of trash comments',
+ 'spam' => '(int) Number of spam comments',
+ 'post_trashed' => '(int) Number of comments whose parent post has been trashed',
+ 'total_comments' => '(int) Combined number of comments in each category',
)
) );
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-media-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-media-v1-2-endpoint.php
index 06c0b2d3..413e3b94 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-media-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-media-v1-2-endpoint.php
@@ -1,6 +1,6 @@
<?php
-require_once( JETPACK__PLUGIN_DIR . 'sal/class.json-api-date.php' );
+jetpack_require_lib( 'class.media' );
new WPCOM_JSON_API_Get_Media_v1_2_Endpoint( array(
'description' => 'Get a single media item (by ID).',
@@ -36,9 +36,9 @@ new WPCOM_JSON_API_Get_Media_v1_2_Endpoint( array(
'videopress_guid' => '(string) (Video only) VideoPress GUID of the video when uploaded on a blog with VideoPress',
'videopress_processing_done' => '(bool) (Video only) If the video is uploaded on a blog with VideoPress, this will return the status of processing on the video.',
'revision_history' => '(object) An object with `items` and `original` keys. ' .
- '`original` is an object with data about the original image. ' .
- '`items` is an array of snapshots of the previous images of this Media. ' .
- 'Each item has the `URL`, `file, `extension`, `date`, and `mime_type` fields.'
+ '`original` is an object with data about the original image. ' .
+ '`items` is an array of snapshots of the previous images of this Media. ' .
+ 'Each item has the `URL`, `file, `extension`, `date`, and `mime_type` fields.'
),
'example_request' => 'https://public-api.wordpress.com/rest/v1.2/sites/82974409/media/934',
@@ -58,7 +58,7 @@ class WPCOM_JSON_API_Get_Media_v1_2_Endpoint extends WPCOM_JSON_API_Get_Media_v1
}
$media_item = get_post( $media_id );
- $response->modified = WPCOM_JSON_API_Date::format_date( $media_item->post_modified_gmt, $media_item->post_modified );
+ $response->modified = (string) $this->format_date( $media_item->post_modified_gmt, $media_item->post_modified );
// expose `revision_history` object
$response->revision_history = (object) array(
@@ -69,3 +69,4 @@ class WPCOM_JSON_API_Get_Media_v1_2_Endpoint extends WPCOM_JSON_API_Get_Media_v1
return $response;
}
}
+
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php
index 4cb99d0d..c7dbcb24 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php
@@ -120,6 +120,12 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
'podcasting_archive',
'is_domain_only',
'is_automated_transfer',
+ 'is_wpcom_store',
+ 'signup_is_store',
+ 'has_pending_automated_transfer',
+ 'woocommerce_is_active',
+ 'design_type',
+ 'site_goals'
);
protected static $jetpack_response_field_additions = array(
@@ -135,7 +141,11 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
'publicize_permanently_disabled',
'ak_vp_bundle_enabled',
'is_automated_transfer',
- 'frame_nonce'
+ 'is_wpcom_store',
+ 'woocommerce_is_active',
+ 'frame_nonce',
+ 'design_type',
+ 'wordads'
);
private $site;
@@ -210,8 +220,21 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
return $this->render_response_keys( $response_keys );
}
- private function has_blog_access( $token_details, $wpcom_blog_id ) {
- if ( is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
+ /**
+ * Checks that the current user has access to the current blog,
+ * and failing that checks that we have a valid blog token.
+ *
+ * @param $token_details array Details obtained from the authorization token
+ * @param $blog_id int The server-side blog id on wordpress.com
+ *
+ * @return bool
+ */
+ private function has_blog_access( $token_details, $blog_id ) {
+ $current_blog_id = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ?
+ $blog_id :
+ get_current_blog_id();
+
+ if ( is_user_member_of_blog( get_current_user_id(), $current_blog_id ) ) {
return true;
}
@@ -223,7 +246,7 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
if (
'jetpack' === $token_details['auth'] &&
'blog' === $token_details['access'] &&
- $wpcom_blog_id === $token_details['blog_id']
+ $current_blog_id === $token_details['blog_id']
) {
return true;
}
@@ -507,6 +530,34 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
case 'blog_public':
$options[ $key ] = $site->get_blog_public();
break;
+ case 'is_wpcom_store':
+ $options[ $key ] = $site->is_wpcom_store();
+ break;
+ case 'signup_is_store':
+ $signup_is_store = $site->signup_is_store();
+
+ if ( $signup_is_store ) {
+ $options[ $key ] = $site->signup_is_store();
+ }
+
+ break;
+ case 'has_pending_automated_transfer':
+ $has_pending_automated_transfer = $site->has_pending_automated_transfer();
+
+ if ( $has_pending_automated_transfer ) {
+ $options[ $key ] = true;
+ }
+
+ break;
+ case 'woocommerce_is_active':
+ $options[ $key ] = $site->woocommerce_is_active();
+ break;
+ case 'design_type':
+ $options[ $key ] = $site->get_design_type();
+ break;
+ case 'site_goals':
+ $options[ $key ] = $site->get_site_goals();
+ break;
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-endpoint.php
index 9ef1e64f..95d11c58 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-endpoint.php
@@ -60,8 +60,7 @@ class WPCOM_JSON_API_List_Media_Endpoint extends WPCOM_JSON_API_Endpoint {
'post_parent' => $args['parent_id'],
'offset' => $args['offset'],
'numberposts' => $args['number'],
- 'post_mime_type' => $args['mime_type'],
- 'suppress_filters' => false,
+ 'post_mime_type' => $args['mime_type']
) );
$response = array();
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-2-endpoint.php
index 3b20fa08..0ffd971b 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-2-endpoint.php
@@ -66,8 +66,8 @@ class WPCOM_JSON_API_List_Media_v1_2_Endpoint extends WPCOM_JSON_API_List_Media_
foreach ( $media_list as $index => $media_item ) {
// expose `revision_history` object for each image
$media_item->revision_history = (object) array(
- 'items' => (array) Media::get_revision_history( $media_item->ID ),
- 'original' => (object) Media::get_original_media( $media_item->ID )
+ 'items' => (array) Jetpack_Media::get_revision_history( $media_item->ID ),
+ 'original' => (object) Jetpack_Media::get_original_media( $media_item->ID )
);
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php
index 69d5bf47..27b1cf0e 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php
@@ -39,12 +39,7 @@ class WPCOM_JSON_API_List_Post_Type_Taxonomies_Endpoint extends WPCOM_JSON_API_E
$this->load_theme_functions();
}
- /** This filter is documented in jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php */
- if ( apply_filters( 'rest_api_localize_response', false ) ) {
- // API localization occurs after the initial taxonomies have been
- // registered, so re-register if localizing response
- create_initial_taxonomies();
- }
+ $this->localize_initial_taxonomies( $post_type );
$args = $this->query_args();
@@ -79,4 +74,25 @@ class WPCOM_JSON_API_List_Post_Type_Taxonomies_Endpoint extends WPCOM_JSON_API_E
'taxonomies' => $formatted_taxonomy_objects,
);
}
+
+ protected function localize_initial_taxonomies( $post_type ) {
+ /** This filter is documented in jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php */
+ if ( ! apply_filters( 'rest_api_localize_response', false ) ) {
+ return;
+ }
+
+ // Since recreating initial taxonomies will restore the default post
+ // types to which they are associated, save post type's taxonomies in
+ // case it was customized via `register_taxonomy_for_object_type`
+ $post_type_taxonomies = get_object_taxonomies( $post_type );
+
+ // API localization occurs after the initial taxonomies have been
+ // registered, so re-register if localizing response
+ create_initial_taxonomies();
+
+ // Restore registered taxonomies for post type
+ foreach ( $post_type_taxonomies as $taxonomy ) {
+ register_taxonomy_for_object_type( $taxonomy, $post_type );
+ }
+ }
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php
index d6cbefa8..06ac5747 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php
@@ -108,6 +108,9 @@ class WPCOM_JSON_API_List_Post_Types_Endpoint extends WPCOM_JSON_API_Endpoint {
return false;
}
- return in_array( $post_type, $featured_content[0]['post_types'] );
+ if ( is_array( $featured_content[0]['post_types'] ) ) {
+ return in_array( $post_type, $featured_content[0]['post_types'] );
+ }
+ return $post_type === $featured_content[0]['post_types'];
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-roles-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-roles-endpoint.php
index 028aabd7..733f26f7 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-roles-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-roles-endpoint.php
@@ -4,7 +4,7 @@ new WPCOM_JSON_API_List_Roles_Endpoint( array(
'description' => 'List the user roles of a site.',
'group' => '__do_not_document',
'stat' => 'roles:list',
-
+ 'max_version' => '1.1',
'method' => 'GET',
'path' => '/sites/%s/roles',
'path_labels' => array(
@@ -26,6 +26,32 @@ new WPCOM_JSON_API_List_Roles_Endpoint( array(
)
) );
+new WPCOM_JSON_API_List_Roles_Endpoint( array(
+ 'description' => 'List the user roles of a site.',
+ 'group' => '__do_not_document',
+ 'stat' => 'roles:list',
+ 'min_version' => '1.2',
+ 'force' => 'wpcom',
+ 'method' => 'GET',
+ 'path' => '/sites/%s/roles',
+ 'path_labels' => array(
+ '$site' => '(int|string) Site ID or domain',
+ ),
+
+ 'query_parameters' => array(),
+
+ 'response_format' => array(
+ 'roles' => '(array:role) Array of role objects.',
+ ),
+
+ 'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/82974409/roles',
+ 'example_request_data' => array(
+ 'headers' => array(
+ 'authorization' => 'Bearer YOUR_API_TOKEN',
+ ),
+ ),
+) );
+
class WPCOM_JSON_API_List_Roles_Endpoint extends WPCOM_JSON_API_Endpoint {
var $response_format = array(
@@ -60,26 +86,45 @@ class WPCOM_JSON_API_List_Roles_Endpoint extends WPCOM_JSON_API_Endpoint {
// /sites/%s/roles/ -> $blog_id
function callback( $path = '', $blog_id = 0 ) {
-
$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
if ( is_wp_error( $blog_id ) ) {
return $blog_id;
}
- if ( ! current_user_can( 'list_users' ) ) {
- return new WP_Error( 'unauthorized', 'User cannot view roles for specified site', 403 );
- }
-
$roles = array();
- $wp_roles= new WP_Roles();
- $role_names = $wp_roles->get_names();
- $role_keys = array_keys( $role_names );
+ $sal_site = $this->get_platform()->get_site( $blog_id );
+ $wp_roles = $sal_site->get_roles();
+
+ // Check if the site is connected and talks to us on a regular basis
+ $is_connected = $sal_site->is_connected_site();
+ if ( is_wp_error( $is_connected ) ) {
+ return $is_connected;
+ }
+
+ if ( ! $sal_site->current_user_can( 'list_users' ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot view roles for specified site', 403 );
+ }
- foreach ( (array) $role_keys as $role_key ) {
- $role_details = get_role( $role_key );
- $role_details->display_name = translate_user_role( $role_names[$role_key] );
- $roles[] = $role_details;
+ if ( method_exists( $wp_roles, 'get_names' ) ) {
+ $role_names = $wp_roles->get_names();
+
+ $role_keys = array_keys( $role_names );
+
+ foreach ( (array) $role_keys as $role_key ) {
+ $role_details = get_role( $role_key );
+ $role_details->display_name = translate_user_role( $role_names[$role_key] );
+ $roles[] = $role_details;
+ }
+ } else {
+ // Jetpack Shadow Site side of things.
+ foreach ( $wp_roles as $role_key => $role ) {
+ $roles[] = (object) array(
+ 'name' => $role_key,
+ 'display_name' => $role['name'],
+ 'capabilities' => (object) $role['capabilities']
+ );
+ }
}
// Sort the array so roles with the most number of capabilities comes first, then the next role, and so on
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php
index e5ae428c..09d3f50c 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php
@@ -556,16 +556,16 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
if ( !empty( $include ) ) {
$include = preg_replace( '/[^0-9,]+/', '', $include );
- $_attachments = get_posts( array( 'include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $_attachments = get_posts( array( 'include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif ( !empty( $exclude ) ) {
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
- $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
} else {
- $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
}
if ( ! empty( $attachments ) ) {
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php
index 2668a259..418cfb16 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php
@@ -324,16 +324,16 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
if ( !empty( $include ) ) {
$include = preg_replace( '/[^0-9,]+/', '', $include );
- $_attachments = get_posts( array( 'include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $_attachments = get_posts( array( 'include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[$val->ID] = $_attachments[$key];
}
} elseif ( !empty( $exclude ) ) {
$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
- $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
} else {
- $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby, 'suppress_filters' => false ) );
+ $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby ) );
}
if ( ! empty( $attachments ) ) {
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php
index 5320978c..1c08060b 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php
@@ -33,7 +33,7 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
}
if ( ! current_user_can( 'edit_posts' ) ) {
- return new WP_Error( 'unauthorized', 'Your token must have permission to post on this blog.', 403 );
+ return new WP_Error( 'unauthorized', __( 'Your token must have permission to post on this blog.', 'jetpack' ), 403 );
}
$args = $this->query_args();
@@ -41,17 +41,17 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
// quick validation
if ( ! preg_match_all( '|^\s*(https?://[^\s"]+)\s*$|im', $embed_url, $matches ) ) {
- return new WP_Error( 'invalid_embed_url', 'The embed_url parameter must be a valid URL.', 400 );
+ return new WP_Error( 'invalid_embed_url', __( 'The embed_url parameter must be a valid URL.', 'jetpack' ), 400 );
}
if ( count( $matches[1] ) > 1 ) {
- return new WP_Error( 'invalid_embed', 'Only one embed can be rendered at a time.', 400 );
+ return new WP_Error( 'invalid_embed', __( 'Only one embed can be rendered at a time.', 'jetpack' ), 400 );
}
$embed_url = array_shift( $matches[1] );
$parts = parse_url( $embed_url );
if ( ! $parts ) {
- return new WP_Error( 'invalid_embed_url', 'The embed_url parameter must be a valid URL.', 400 );
+ return new WP_Error( 'invalid_embed_url', __( 'The embed_url parameter must be a valid URL.', 'jetpack' ), 400 );
}
global $wp_embed;
@@ -60,7 +60,7 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
// if nothing happened, then the shortcode does not exist.
$is_an_embed = ( $embed_url != $render['result'] && $wp_embed->maybe_make_link( $embed_url ) != $render['result'] );
if ( ! $is_an_embed ) {
- return new WP_Error( 'invalid_embed', 'The requested URL is not an embed.', 400 );
+ return new WP_Error( 'invalid_embed', __( 'The requested URL is not an embed.', 'jetpack' ), 400 );
}
// our output for this endpoint..
@@ -72,4 +72,4 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
return $return;
}
-} \ No newline at end of file
+}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php
index b450c3ea..ecc9eaf8 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php
@@ -99,6 +99,7 @@ new WPCOM_JSON_API_Site_Settings_Endpoint( array(
'site_icon' => '(int) Media attachment ID to use as site icon. Set to zero or an otherwise empty value to clear',
'api_cache' => '(bool) Turn on/off the Jetpack JSON API cache',
'posts_per_page' => '(int) Number of posts to show on blog pages',
+ 'net_neutrality' => '(bool) Whether to show the net neutrality modal for a site',
'posts_per_rss' => '(int) Number of posts to show in the RSS feed',
'rss_use_excerpt' => '(bool) Whether the RSS feed will use post excerpts',
),
@@ -131,6 +132,8 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
}
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ // Source & include the infinite scroll compatibility files prior to loading theme functions
+ add_filter( 'restapi_theme_action_copy_dirs', array( 'WPCOM_JSON_API_Site_Settings_Endpoint', 'wpcom_restapi_copy_theme_plugin_actions' ) );
$this->load_theme_functions();
}
@@ -161,6 +164,37 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
}
/**
+ * Includes additional theme-specific files to be included in REST API theme
+ * context loading action copying.
+ *
+ * @see WPCOM_JSON_API_Endpoint#load_theme_functions
+ * @see the_neverending_home_page_theme_support
+ */
+ function wpcom_restapi_copy_theme_plugin_actions( $copy_dirs ) {
+ $theme_name = get_stylesheet();
+ $default_file_name = WP_CONTENT_DIR . "/mu-plugins/infinity/themes/{$theme_name}.php";
+
+ /**
+ * Filter the path to the Infinite Scroll compatibility file.
+ *
+ * @module infinite-scroll
+ *
+ * @since 2.0.0
+ *
+ * @param string $str IS compatibility file path.
+ * @param string $theme_name Theme name.
+ */
+ $customization_file = apply_filters( 'infinite_scroll_customization_file', $default_file_name, $theme_name );
+
+ if ( is_readable( $customization_file ) ) {
+ require_once $customization_file;
+ $copy_dirs[] = $customization_file;
+ }
+
+ return $copy_dirs;
+ }
+
+ /**
* Determines whether jetpack_relatedposts is supported
*
* @return bool
@@ -278,6 +312,11 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
$api_cache = $is_jetpack ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true;
+ $net_neutrality_options = get_option( 'net_neutrality_options_2017' );
+ $net_neutrality = ( $net_neutrality_options && ! empty( $net_neutrality_options['enabled'] ) )
+ ? true
+ : false;
+
$response[ $key ] = array(
// also exists as "options"
@@ -343,6 +382,7 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
'amp_is_enabled' => (bool) function_exists( 'wpcom_is_amp_enabled' ) && wpcom_is_amp_enabled( $blog_id ),
'api_cache' => $api_cache,
'posts_per_page' => (int) get_option( 'posts_per_page' ),
+ 'net_neutrality' => $net_neutrality,
'posts_per_rss' => (int) get_option( 'posts_per_rss' ),
'rss_use_excerpt' => (bool) get_option( 'rss_use_excerpt' ),
);
@@ -350,6 +390,25 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
$response[ $key ]['wpcom_publish_posts_with_markdown'] = (bool) WPCom_Markdown::is_posting_enabled();
$response[ $key ]['wpcom_publish_comments_with_markdown'] = (bool) WPCom_Markdown::is_commenting_enabled();
+
+ // WPCOM-specific Infinite Scroll Settings
+ if ( is_callable( array( 'The_Neverending_Home_Page', 'get_settings' ) ) ) {
+ /**
+ * Clear the cached copy of widget info so it's pulled fresh from blog options.
+ * It was primed during the initial load under the __REST API site__'s context.
+ * @see wp_get_sidebars_widgets https://core.trac.wordpress.org/browser/trunk/src/wp-includes/widgets.php?rev=42374#L931
+ */
+ $GLOBALS['_wp_sidebars_widgets'] = array();
+
+ $infinite_scroll_settings = The_Neverending_Home_Page::get_settings();
+ $response[ $key ]['infinite_scroll'] = get_option( 'infinite_scroll', true ) && $infinite_scroll_settings->type === 'scroll';
+ if ( $infinite_scroll_settings->footer_widgets || 'click' == $infinite_scroll_settings->requested_type ) {
+ // The blog has footer widgets -- infinite scroll is blocked
+ $response[ $key ]['infinite_scroll_blocked'] = 'footer';
+ } else {
+ $response[ $key ]['infinite_scroll_blocked'] = false;
+ }
+ }
}
//allow future versions of this endpoint to support additional settings keys
@@ -412,16 +471,22 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
public function update_settings() {
// $this->input() retrieves posted arguments whitelisted and casted to the $request_format
// specs that get passed in when this class is instantiated
+ $input = $this->input();
+ $unfiltered_input = $this->input( false, false );
/**
* Filters the settings to be updated on the site.
*
* @module json-api
*
* @since 3.6.0
+ * @since 6.1.1 Added $unfiltered_input parameter.
*
- * @param array $input Associative array of site settings to be updated.
+ * @param array $input Associative array of site settings to be updated.
+ * Cast and filtered based on documentation.
+ * @param array $unfiltered_input Associative array of site settings to be updated.
+ * Neither cast nor filtered. Contains raw input.
*/
- $input = apply_filters( 'rest_api_update_site_settings', $this->input() );
+ $input = apply_filters( 'rest_api_update_site_settings', $input, $unfiltered_input );
$blog_id = get_current_blog_id();
@@ -695,6 +760,15 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
}
break;
+ case 'net_neutrality':
+ $original_value = $value;
+ $value = array( 'enabled' => (bool) $value );
+ if ( update_option( 'net_neutrality_options_2017', $value ) ) {
+ $updated[ $key ] = $original_value;
+ }
+
+ break;
+
default:
//allow future versions of this endpoint to support additional settings keys
if ( has_filter( 'site_settings_endpoint_update_' . $key ) ) {
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php
index 388eac66..e494a1bb 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php
@@ -96,6 +96,7 @@ new WPCOM_JSON_API_Site_Settings_V1_2_Endpoint( array(
'site_icon' => '(int) Media attachment ID to use as site icon. Set to zero or an otherwise empty value to clear',
'api_cache' => '(bool) Turn on/off the Jetpack JSON API cache',
'posts_per_page' => '(int) Number of posts to show on blog pages',
+ 'net_neutrality' => '(bool) Whether the net neutrality modal is enabled for this site',
'posts_per_rss' => '(int) Number of posts to show in the RSS feed',
'rss_use_excerpt' => '(bool) Whether the RSS feed will use post excerpts',
),
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php
index 680d70b5..316c64a4 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php
@@ -1,11 +1,4 @@
<?php
-/**
- * WARNING: This file is distributed verbatim in Jetpack.
- * There should be nothing WordPress.com specific in this file.
- *
- * @hide-in-jetpack
- * @autounit api-v1 site-settings
- */
new WPCOM_JSON_API_Site_Settings_V1_3_Endpoint( array(
'description' => 'Get detailed settings information about a site.',
@@ -96,13 +89,14 @@ new WPCOM_JSON_API_Site_Settings_V1_3_Endpoint( array(
'jetpack_portfolio' => '(bool) Whether portfolio custom post type is enabled for the site',
'jetpack_portfolio_posts_per_page' => '(int) Number of portfolio projects to show per page',
Jetpack_SEO_Utils::FRONT_PAGE_META_OPTION => '(string) The SEO meta description for the site.',
- Jetpack_SEO_Titles::TITLE_FORMATS_OPTION => '(array) SEO meta title formats. Allowed keys: front_page, posts, pages, groups, archives',
+ Jetpack_SEO_Titles::TITLE_FORMATS_OPTION => '(array) SEO meta title formats. Allowed keys: front_page, posts, pages, groups, archives',
'verification_services_codes' => '(array) Website verification codes. Allowed keys: google, pinterest, bing, yandex',
'amp_is_enabled' => '(bool) Whether AMP is enabled for this site',
'podcasting_archive' => '(string) The post category, if any, used for publishing podcasts',
'site_icon' => '(int) Media attachment ID to use as site icon. Set to zero or an otherwise empty value to clear',
'api_cache' => '(bool) Turn on/off the Jetpack JSON API cache',
'posts_per_page' => '(int) Number of posts to show on blog pages',
+ 'net_neutrality' => '(bool) Whether the net neutrality modal is enabled for this site',
'posts_per_rss' => '(int) Number of posts to show in the RSS feed',
'rss_use_excerpt' => '(bool) Whether the RSS feed will use post excerpts',
),
@@ -115,12 +109,14 @@ new WPCOM_JSON_API_Site_Settings_V1_3_Endpoint( array(
) );
class WPCOM_JSON_API_Site_Settings_V1_3_Endpoint extends WPCOM_JSON_API_Site_Settings_V1_2_Endpoint {
- public static $wga_defaults = array(
- 'code' => '',
- 'anonymize_ip' => false,
- 'ec_track_purchases' => false,
- 'ec_track_add_to_cart' => false
- );
+ protected function get_defaults() {
+ return array(
+ 'code' => '',
+ 'anonymize_ip' => false,
+ 'ec_track_purchases' => false,
+ 'ec_track_add_to_cart' => false
+ );
+ }
function callback( $path = '', $blog_id = 0 ) {
add_filter( 'site_settings_endpoint_get', array( $this, 'filter_site_settings_endpoint_get' ) );
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php
index de3cd5a9..929acde3 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php
@@ -1,11 +1,4 @@
<?php
-/**
- * WARNING: This file is distributed verbatim in Jetpack.
- * There should be nothing WordPress.com specific in this file.
- *
- * @hide-in-jetpack
- * @autounit api-v1 site-settings
- */
new WPCOM_JSON_API_Site_Settings_V1_4_Endpoint( array(
'description' => 'Get detailed settings information about a site.',
@@ -103,6 +96,7 @@ new WPCOM_JSON_API_Site_Settings_V1_4_Endpoint( array(
'site_icon' => '(int) Media attachment ID to use as site icon. Set to zero or an otherwise empty value to clear',
'api_cache' => '(bool) Turn on/off the Jetpack JSON API cache',
'posts_per_page' => '(int) Number of posts to show on blog pages',
+ 'net_neutrality' => '(bool) Whether the net neutrality modal is enabled for this site',
'posts_per_rss' => '(int) Number of posts to show in the RSS feed',
'rss_use_excerpt' => '(bool) Whether the RSS feed will use post excerpts',
),
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php
index 72c04a8e..1e1a1f1b 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php
@@ -321,8 +321,12 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
$new_status = isset( $input['status'] ) ? $input['status'] : $last_status;
// Make sure that drafts get the current date when transitioning to publish if not supplied in the post.
+ // Similarly, scheduled posts that are manually published before their scheduled date should have the date reset.
$date_in_past = ( strtotime($post->post_date_gmt) < time() );
- if ( 'publish' === $new_status && 'draft' === $last_status && ! isset( $input['date_gmt'] ) && $date_in_past ) {
+ $reset_draft_date = 'publish' === $new_status && 'draft' === $last_status && ! isset( $input['date_gmt'] ) && $date_in_past;
+ $reset_scheduled_date = 'publish' === $new_status && 'future' === $last_status && ! isset( $input['date_gmt'] ) && ! $date_in_past;
+
+ if ( $reset_draft_date || $reset_scheduled_date ) {
$input['date_gmt'] = gmdate( 'Y-m-d H:i:s' );
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php
index 98186ca3..6deae172 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php
@@ -265,8 +265,12 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
$new_status = isset( $input['status'] ) ? $input['status'] : $last_status;
// Make sure that drafts get the current date when transitioning to publish if not supplied in the post.
+ // Similarly, scheduled posts that are manually published before their scheduled date should have the date reset.
$date_in_past = ( strtotime($post->post_date_gmt) < time() );
- if ( 'publish' === $new_status && 'draft' === $last_status && ! isset( $input['date_gmt'] ) && $date_in_past ) {
+ $reset_draft_date = 'publish' === $new_status && 'draft' === $last_status && ! isset( $input['date_gmt'] ) && $date_in_past;
+ $reset_scheduled_date = 'publish' === $new_status && 'future' === $last_status && ! isset( $input['date_gmt'] ) && ! $date_in_past;
+
+ if ( $reset_draft_date || $reset_scheduled_date ) {
$input['date_gmt'] = gmdate( 'Y-m-d H:i:s' );
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-upload-media-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-upload-media-v1-1-endpoint.php
index 7aea6949..a46d0afd 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-upload-media-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-upload-media-v1-1-endpoint.php
@@ -159,6 +159,10 @@ class WPCOM_JSON_API_Upload_Media_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
$input = $this->input( true );
$media_files = ! empty( $input['media'] ) ? $input['media'] : array();
+ if ( empty( $media_files ) ) {
+ return false;
+ }
+
foreach ( $media_files as $media_item ) {
if ( ! preg_match( '@^video/@', $media_item['type'] ) ) {
return false;
diff --git a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-sync-endpoint.php b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-sync-endpoint.php
index ef5831e8..cba22c24 100644
--- a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-sync-endpoint.php
+++ b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-sync-endpoint.php
@@ -148,6 +148,7 @@ class Jetpack_JSON_API_Sync_Object extends Jetpack_JSON_API_Sync_Endpoint {
return array(
'objects' => $objects,
+ 'codec' => $codec->name(),
);
}
}
diff --git a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-user-connect-endpoint.php b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-user-connect-endpoint.php
index 8b758559..b30597de 100644
--- a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-user-connect-endpoint.php
+++ b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-user-connect-endpoint.php
@@ -27,5 +27,4 @@ class Jetpack_JSON_API_User_Connect_Endpoint extends Jetpack_JSON_API_Endpoint {
$this->user_token = sanitize_text_field( $input[ 'user_token'] );
return parent::validate_input( $user_id );
}
-
}
diff --git a/plugins/jetpack/json-endpoints/jetpack/json-api-jetpack-endpoints.php b/plugins/jetpack/json-endpoints/jetpack/json-api-jetpack-endpoints.php
index ee138cf1..919c9ee6 100644
--- a/plugins/jetpack/json-endpoints/jetpack/json-api-jetpack-endpoints.php
+++ b/plugins/jetpack/json-endpoints/jetpack/json-api-jetpack-endpoints.php
@@ -592,7 +592,8 @@ new Jetpack_JSON_API_Sync_Object( array(
'object_ids' => '(array) The IDs of the objects',
),
'response_format' => array(
- 'objects' => '(string) The encoded objects'
+ 'objects' => '(string) The encoded objects',
+ 'codec' => '(string) The codec used to encode the objects, deflate-json-array or simple'
),
'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/example.wordpress.org/sync/object?module_name=posts&object_type=post&object_ids[]=1&object_ids[]=2&object_ids[]=3'
) );