summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2016-07-28 23:29:30 -0400
committerAnthony G. Basile <blueness@gentoo.org>2016-07-28 23:29:30 -0400
commit5c4552fad98db23b2698e8a598bf20f42cb430ef (patch)
tree61fc1f692646288704376f32d914eeef152e375e /plugins/jetpack/json-endpoints
parentUpdate plugin jecpack to 4.0.4 (diff)
downloadblogs-gentoo-5c4552fad98db23b2698e8a598bf20f42cb430ef.tar.gz
blogs-gentoo-5c4552fad98db23b2698e8a598bf20f42cb430ef.tar.bz2
blogs-gentoo-5c4552fad98db23b2698e8a598bf20f42cb430ef.zip
Update plugin jetpack to 4.1.1
Diffstat (limited to 'plugins/jetpack/json-endpoints')
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-comment-endpoint.php18
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-post-v1-1-endpoint.php16
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-endpoint.php220
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-v1-2-endpoint.php25
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-get-term-endpoint.php38
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-comments-endpoint.php14
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-embeds-endpoint.php2
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-1-endpoint.php1
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php71
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-types-endpoint.php11
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-endpoint.php2
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php4
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-shortcodes-endpoint.php4
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-terms-endpoint.php87
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-list-users-endpoint.php14
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php3
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-post-endpoint.php22
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-post-v1-1-endpoint.php526
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-render-embed-endpoint.php11
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-render-endpoint.php25
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-render-shortcode-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-sharing-buttons-endpoint.php6
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php40
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-site-user-endpoint.php23
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-invites-endpoint.php2
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-endpoint.php14
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-1-endpoint.php102
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-v1-2-endpoint.php125
-rw-r--r--plugins/jetpack/json-endpoints/class.wpcom-json-api-update-term-endpoint.php164
-rw-r--r--plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-plugins-modify-endpoint.php2
30 files changed, 889 insertions, 709 deletions
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-comment-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-comment-endpoint.php
index 82359f63..d8de1295 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-comment-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-comment-endpoint.php
@@ -121,7 +121,7 @@ abstract class WPCOM_JSON_API_Comment_Endpoint extends WPCOM_JSON_API_Endpoint {
'ID' => (int) $post->ID,
'title' => (string) get_the_title( $post->ID ),
'type' => (string) $post->post_type,
- 'link' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ),
+ 'link' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ),
);
break;
case 'author' :
@@ -155,7 +155,7 @@ abstract class WPCOM_JSON_API_Comment_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[$key] = (object) array(
'ID' => (int) $parent->comment_ID,
'type' => (string) ( $parent->comment_type ? $parent->comment_type : 'comment' ),
- 'link' => (string) $this->get_comment_link( $blog_id, $parent->comment_ID ),
+ 'link' => (string) $this->links->get_comment_link( $blog_id, $parent->comment_ID ),
);
} else {
$response[$key] = false;
@@ -177,14 +177,12 @@ abstract class WPCOM_JSON_API_Comment_Endpoint extends WPCOM_JSON_API_Endpoint {
case 'meta' :
$response[$key] = (object) array(
'links' => (object) array(
- 'self' => (string) $this->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID ),
- 'help' => (string) $this->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'help' ),
- 'site' => (string) $this->get_site_link( $this->api->get_blog_id_for_output() ),
- 'post' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $comment->comment_post_ID ),
- 'replies' => (string) $this->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'replies/' ),
-// 'author' => (string) $this->get_user_link( $comment->user_id ),
-// 'via' => (string) $this->get_post_link( $ping_origin_blog_id, $ping_origin_post_id ), // Ping/trackbacks
- 'likes' => (string) $this->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'likes/' ),
+ 'self' => (string) $this->links->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID ),
+ 'help' => (string) $this->links->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'help' ),
+ 'site' => (string) $this->links->get_site_link( $this->api->get_blog_id_for_output() ),
+ 'post' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $comment->comment_post_ID ),
+ 'replies' => (string) $this->links->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'replies/' ),
+ 'likes' => (string) $this->links->get_comment_link( $this->api->get_blog_id_for_output(), $comment->comment_ID, 'likes/' ),
),
);
break;
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-post-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-post-v1-1-endpoint.php
index 517630a6..6f79222a 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-post-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-post-v1-1-endpoint.php
@@ -10,13 +10,19 @@ class WPCOM_JSON_API_Get_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_End
$args = $this->query_args();
- if ( false === strpos( $path, '/posts/slug:' ) ) {
- $get_by = 'ID';
- } else {
- $get_by = 'name';
+ if ( false !== strpos( $path, '/posts/slug:' ) ) {
+ $post_id = $this->get_platform()->get_site( $blog_id )->get_post_id_by_name( $post_id );
+ if ( is_wp_error( $post_id ) ) {
+ return $post_id;
+ }
}
- $return = $this->get_post_by( $get_by, $post_id, $args['context'] );
+ if ( defined( 'IS_WPCOM' ) && IS_WPCOM &&
+ ! in_array( get_post_type( $post_id ), array( false, 'post', 'page', 'revision' ) ) ) {
+ $this->load_theme_functions();
+ }
+
+ $return = $this->get_post_by( 'ID', $post_id, $args['context'] );
if ( !$return || is_wp_error( $return ) ) {
return $return;
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 852b6e89..95a42b41 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
@@ -1,5 +1,4 @@
<?php
-
class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
public static $site_format = array(
@@ -28,6 +27,24 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
'meta' => '(object) Meta data',
);
+ protected static $no_member_fields = array(
+ 'ID',
+ 'name',
+ 'description',
+ 'URL',
+ 'jetpack',
+ 'post_count',
+ 'subscribers_count',
+ 'lang',
+ 'locale',
+ 'icon',
+ 'logo',
+ 'visible',
+ 'is_private',
+ 'is_following',
+ 'meta',
+ );
+
protected static $site_options_format = array(
'timezone',
'gmt_offset',
@@ -68,21 +85,26 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
'frame_nonce',
'page_on_front',
'page_for_posts',
+ 'headstart',
'ak_vp_bundle_enabled'
);
- protected static $jetpack_response_field_additions = array(
+ protected static $jetpack_response_field_additions = array(
+ 'subscribers_count',
+ );
+
+ protected static $jetpack_response_field_member_additions = array(
'capabilities',
'plan',
- 'subscribers_count'
);
- protected static $jetpack_response_option_additions = array(
+ protected static $jetpack_response_option_additions = array(
'publicize_permanently_disabled',
'ak_vp_bundle_enabled'
);
private $site;
+
// protected $compact = null;
protected $fields_to_include = '_all';
protected $options_to_include = '_all';
@@ -103,6 +125,11 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
return $blog_id;
}
+ // TODO: enable this when we can do so without being interfered with by
+ // other endpoints that might be wrapping this one.
+ // Uncomment and see failing test: test_jetpack_site_should_have_true_jetpack_property_via_site_meta
+ // $this->filter_fields_and_options();
+
$response = $this->build_current_site_response();
/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
@@ -118,40 +145,36 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
$this->options_to_include = empty( $query_args['options'] ) ? '_all' : array_map( 'trim', explode( ',', $query_args['options'] ) );
}
- protected function include_response_field( $field ) {
- if ( is_array( $this->fields_to_include ) ) {
- return in_array( $field, $this->fields_to_include );
- }
- return true;
- }
-
/**
* Collects the necessary information to return for a site's response.
*
* @return (array)
*/
public function build_current_site_response() {
+
$blog_id = (int) $this->api->get_blog_id_for_output();
- $this->site = wpcom_get_sal_site( $blog_id );
+ $this->site = $this->get_platform()->get_site( $blog_id );
- // Allow update in later versions
/**
- * Filter the structure of information about the site to return.
- *
- * @module json-api
- *
- * @since 3.9.3
- *
- * @param array $site_format Data structure.
- */
- $response_format = apply_filters( 'sites_site_format', self::$site_format );
+ * Filter the structure of information about the site to return.
+ *
+ * @module json-api
+ *
+ * @since 3.9.3
+ *
+ * @param array $site_format Data structure.
+ */
$default_fields = array_keys( apply_filters( 'sites_site_format', self::$site_format ) );
$response_keys = is_array( $this->fields_to_include ) ?
array_intersect( $default_fields, $this->fields_to_include ) :
$default_fields;
+ if ( ! is_user_member_of_blog( get_current_user(), $blog_id ) ) {
+ $response_keys = array_intersect( $response_keys, self::$no_member_fields );
+ }
+
return $this->render_response_keys( $response_keys );
}
@@ -179,13 +202,13 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[ $key ] = $this->site->blog_id;
break;
case 'name' :
- $response[ $key ] = (string) htmlspecialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
+ $response[ $key ] = $this->site->get_name();
break;
case 'description' :
- $response[ $key ] = (string) htmlspecialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES );
+ $response[ $key ] = $this->site->get_description();
break;
case 'URL' :
- $response[ $key ] = (string) home_url();
+ $response[ $key ] = $this->site->get_url();
break;
case 'user_can_manage' :
$response[ $key ] = $this->site->user_can_manage();
@@ -200,7 +223,7 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
break;
case 'post_count' :
if ( $is_user_logged_in ) {
- $response[ $key ] = (int) wp_count_posts( 'post' )->publish;
+ $response[ $key ] = $this->site->get_post_count();
}
break;
case 'icon' :
@@ -217,7 +240,7 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[ $key ] = $this->site->is_following();
break;
case 'options':
- // small optimisation - don't recalculate
+ // small optimisation - don't recalculate
$all_options = apply_filters( 'sites_site_options_format', self::$site_options_format );
$options_response_keys = is_array( $this->options_to_include ) ?
@@ -228,7 +251,7 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
$this->site->after_render_options( $options );
- $response[ $key ] = $options;
+ $response[ $key ] = (object) $options;
break;
case 'meta':
$this->build_meta_response( $response );
@@ -242,16 +265,16 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
case 'jetpack' :
$response[ $key ] = $this->site->is_jetpack();
break;
- case 'single_user_site' :
+ case 'single_user_site' :
$response[ $key ] = $this->site->is_single_user_site();
break;
- case 'is_vip' :
+ case 'is_vip' :
$response[ $key ] = $this->site->is_vip();
break;
case 'is_multisite' :
$response[ $key ] = $this->site->is_multisite();
break;
- case 'capabilities' :
+ case 'capabilities' :
$response[ $key ] = $this->site->get_capabilities();
break;
case 'jetpack_modules':
@@ -270,148 +293,141 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
protected function render_option_keys( &$options_response_keys ) {
if ( ! current_user_can( 'edit_posts' ) ) {
- return;
+ return array();
}
- global $wp_version;
-
$options = array();
+ $site = $this->site;
- $custom_front_page = ( 'page' === get_option( 'show_on_front' ) );
+ $custom_front_page = $site->is_custom_front_page();
+
foreach ( $options_response_keys as $key ) {
switch ( $key ) {
case 'timezone' :
- $options[ $key ] = (string) get_option( 'timezone_string' );
+ $options[ $key ] = $site->get_timezone();
break;
case 'gmt_offset' :
- $options[ $key ] = (float) get_option( 'gmt_offset' );
+ $options[ $key ] = $site->get_gmt_offset();
break;
case 'videopress_enabled' :
- $options[ $key ] = $this->site->has_videopress();
+ $options[ $key ] = $site->has_videopress();
break;
case 'upgraded_filetypes_enabled' :
- $options[ $key ] = $this->site->upgraded_filetypes_enabled();
+ $options[ $key ] = $site->upgraded_filetypes_enabled();
break;
case 'login_url' :
- $options[ $key ] = wp_login_url();
+ $options[ $key ] = $site->get_login_url();
break;
case 'admin_url' :
- $options[ $key ] = get_admin_url();
+ $options[ $key ] = $site->get_admin_url();
break;
case 'is_mapped_domain' :
- $options[ $key ] = $this->site->is_mapped_domain();
+ $options[ $key ] = $site->is_mapped_domain();
break;
case 'is_redirect' :
- $options[ $key ] = $this->site->is_redirect();
+ $options[ $key ] = $site->is_redirect();
break;
case 'unmapped_url' :
- $options[ $key ] = get_site_url( $this->site->blog_id );
+ $options[ $key ] = $site->get_unmapped_url();
break;
case 'featured_images_enabled' :
- $options[ $key ] = $this->site->featured_images_enabled();
+ $options[ $key ] = $site->featured_images_enabled();
break;
case 'theme_slug' :
- $options[ $key ] = get_option( 'stylesheet' );
+ $options[ $key ] = $site->get_theme_slug();
break;
case 'header_image' :
- $options[ $key ] = get_theme_mod( 'header_image_data' );
+ $options[ $key ] = $site->get_header_image();
break;
case 'background_color' :
- $options[ $key ] = get_theme_mod( 'background_color' );
+ $options[ $key ] = $site->get_background_color();
break;
case 'image_default_link_type' :
- $options[ $key ] = get_option( 'image_default_link_type' );
+ $options[ $key ] = $site->get_image_default_link_type();
break;
case 'image_thumbnail_width' :
- $options[ $key ] = (int) get_option( 'thumbnail_size_w' );
+ $options[ $key ] = $site->get_image_thumbnail_width();
break;
case 'image_thumbnail_height' :
- $options[ $key ] = (int) get_option( 'thumbnail_size_h' );
+ $options[ $key ] = $site->get_image_thumbnail_height();
break;
case 'image_thumbnail_crop' :
- $options[ $key ] = get_option( 'thumbnail_crop' );
+ $options[ $key ] = $site->get_image_thumbnail_crop();
break;
case 'image_medium_width' :
- $options[ $key ] = (int) get_option( 'medium_size_w' );
+ $options[ $key ] = $site->get_image_medium_width();
break;
case 'image_medium_height' :
- $options[ $key ] = (int) get_option( 'medium_size_h' );
+ $options[ $key ] = $site->get_image_medium_height();
break;
case 'image_large_width' :
- $options[ $key ] = (int) get_option( 'large_size_w' );
+ $options[ $key ] = $site->get_image_large_width();
break;
case 'image_large_height' :
- $options[ $key ] = (int) get_option( 'large_size_h' );
+ $options[ $key ] = $site->get_image_large_height();
break;
case 'permalink_structure' :
- $options[ $key ] = get_option( 'permalink_structure' );
+ $options[ $key ] = $site->get_permalink_structure();
break;
case 'post_formats' :
- $options[ $key ] = $this->site->get_post_formats();
+ $options[ $key ] = $site->get_post_formats();
break;
case 'default_post_format' :
- $options[ $key ] = get_option( 'default_post_format' );
+ $options[ $key ] = $site->get_default_post_format();
break;
case 'default_category' :
- $options[ $key ] = (int) get_option( 'default_category' );
+ $options[ $key ] = $site->get_default_category();
break;
case 'allowed_file_types' :
- $options[ $key ] = $this->site->allowed_file_types();
+ $options[ $key ] = $site->allowed_file_types();
break;
case 'show_on_front' :
- $options[ $key ] = get_option( 'show_on_front' );
+ $options[ $key ] = $site->get_show_on_front();
break;
/** This filter is documented in modules/likes.php */
case 'default_likes_enabled' :
- $options[ $key ] = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
+ $options[ $key ] = $site->get_default_likes_enabled();
break;
case 'default_sharing_status' :
- $default_sharing_status = false;
- if ( class_exists( 'Sharing_Service' ) ) {
- $ss = new Sharing_Service();
- $blog_services = $ss->get_blog_services();
- $default_sharing_status = ! empty( $blog_services['visible'] );
- }
- $options[ $key ] = (bool) $default_sharing_status;
+ $options[ $key ] = $site->get_default_sharing_status();
break;
case 'default_comment_status' :
- $options[ $key ] = 'closed' !== get_option( 'default_comment_status' );
+ $options[ $key ] = $site->get_default_comment_status();
break;
case 'default_ping_status' :
- $options[ $key ] = 'closed' !== get_option( 'default_ping_status' );
+ $options[ $key ] = $site->default_ping_status();
break;
case 'software_version' :
- $options[ $key ] = $wp_version;
+ $options[ $key ] = $site->get_wordpress_version();
break;
case 'created_at' :
- $options[ $key ] = $this->site->get_registered_date();
+ $options[ $key ] = $site->get_registered_date();
break;
case 'wordads' :
- $options[ $key ] = $this->site->has_wordads();
+ $options[ $key ] = $site->has_wordads();
break;
case 'publicize_permanently_disabled' :
- $publicize_permanently_disabled = false;
- if ( function_exists( 'is_publicize_permanently_disabled' ) ) {
- $publicize_permanently_disabled = is_publicize_permanently_disabled( $this->site->blog_id );
- }
- $options[ $key ] = $publicize_permanently_disabled;
+ $options[ $key ] = $site->is_publicize_permanently_disabled();
break;
case 'frame_nonce' :
- $options[ $key ] = $this->site->get_frame_nonce();
+ $options[ $key ] = $site->get_frame_nonce();
break;
case 'page_on_front' :
if ( $custom_front_page ) {
- $options[ $key ] = (int) get_option( 'page_on_front' );
+ $options[ $key ] = $site->get_page_on_front();
}
break;
case 'page_for_posts' :
if ( $custom_front_page ) {
- $options[ $key ] = (int) get_option( 'page_for_posts' );
+ $options[ $key ] = $site->get_page_for_posts();
}
break;
+ case 'headstart' :
+ $options[ $key ] = $site->is_headstart();
+ break;
case 'ak_vp_bundle_enabled' :
- $options[ $key ] = $this->site->get_ak_vp_bundle_enabled();
+ $options[ $key ] = $site->get_ak_vp_bundle_enabled();
}
}
@@ -419,22 +435,20 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
}
protected function build_meta_response( &$response ) {
- $xmlrpc_scheme = apply_filters( 'wpcom_json_api_xmlrpc_scheme', parse_url( get_option( 'home' ), PHP_URL_SCHEME ) );
- $xmlrpc_url = site_url( 'xmlrpc.php', $xmlrpc_scheme );
$response['meta'] = (object) array(
'links' => (object) array(
- 'self' => (string) $this->get_site_link( $this->site->blog_id ),
- 'help' => (string) $this->get_site_link( $this->site->blog_id, 'help' ),
- 'posts' => (string) $this->get_site_link( $this->site->blog_id, 'posts/' ),
- 'comments' => (string) $this->get_site_link( $this->site->blog_id, 'comments/' ),
- 'xmlrpc' => (string) $xmlrpc_url,
+ 'self' => (string) $this->links->get_site_link( $this->site->blog_id ),
+ 'help' => (string) $this->links->get_site_link( $this->site->blog_id, 'help' ),
+ 'posts' => (string) $this->links->get_site_link( $this->site->blog_id, 'posts/' ),
+ 'comments' => (string) $this->links->get_site_link( $this->site->blog_id, 'comments/' ),
+ 'xmlrpc' => (string) $this->site->get_xmlrpc_url(),
),
);
}
// apply any WPCOM-only response components to a Jetpack site response
public function decorate_jetpack_response( &$response ) {
- $this->site = wpcom_get_sal_site( $blog_id );
+ $this->site = $this->get_platform()->get_site( $response->ID );
// ensure the response is marked as being from Jetpack
$response->jetpack = true;
@@ -445,14 +459,32 @@ class WPCOM_JSON_API_GET_Site_Endpoint extends WPCOM_JSON_API_Endpoint {
$response->{ $key } = $value;
}
+ if ( is_user_member_of_blog( get_current_user(), $response->ID ) ) {
+ $wpcom_member_response = $this->render_response_keys( self::$jetpack_response_field_member_additions );
+
+ foreach( $wpcom_member_response as $key => $value ) {
+ $response->{ $key } = $value;
+ }
+ } else {
+ // ensure private data is not rendered for non members of the site
+ unset( $response->options );
+ unset( $response->is_vip );
+ unset( $response->single_user_site );
+ unset( $response->is_private );
+ unset( $response->capabilities );
+ unset( $response->lang );
+ unset( $response->user_can_manage );
+ unset( $response->is_multisite );
+ unset( $response->plan );
+ }
+
// render additional options
if ( $response->options ) {
$wpcom_options_response = $this->render_option_keys( self::$jetpack_response_option_additions );
- foreach( $wpcom_options_response as $key => $value ) {
+ foreach ( $wpcom_options_response as $key => $value ) {
$response->options[ $key ] = $value;
}
- return (string) get_bloginfo( 'language' );
}
return $response; // possibly no need since it's modified in place
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-v1-2-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-v1-2-endpoint.php
index 6f693e91..898df417 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-v1-2-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-site-v1-2-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
- */
-
class WPCOM_JSON_API_GET_Site_V1_2_Endpoint extends WPCOM_JSON_API_GET_Site_Endpoint {
public static $site_format = array(
@@ -13,7 +6,9 @@ class WPCOM_JSON_API_GET_Site_V1_2_Endpoint extends WPCOM_JSON_API_GET_Site_Endp
'name' => '(string) Title of site',
'description' => '(string) Tagline or description of site',
'URL' => '(string) Full URL to the site',
+ 'capabilities' => '(array) Array of capabilities for the current user on this site.',
'jetpack' => '(bool) Whether the site is a Jetpack site or not',
+ 'is_multisite' => '(bool) Whether the site is a Multisite site or not. Always true for WP.com sites.',
'post_count' => '(int) The number of posts the site has',
'subscribers_count' => '(int) The number of subscribers the site has',
'locale' => '(string) Primary locale code of the site',
@@ -21,31 +16,23 @@ class WPCOM_JSON_API_GET_Site_V1_2_Endpoint extends WPCOM_JSON_API_GET_Site_Endp
'logo' => '(array) The site logo, set in the Customizer',
'visible' => '(bool) If this site is visible in the user\'s site list',
'is_private' => '(bool) If the site is a private site or not',
+ 'single_user_site' => '(bool) Whether the site is single user. Only returned for WP.com sites and for Jetpack sites with version 3.4 or higher.',
+ 'is_vip' => '(bool) If the site is a VIP site or not.',
'is_following' => '(bool) If the current user is subscribed to this site in the reader',
'options' => '(array) An array of options/settings for the blog. Only viewable by users with post editing rights to the site. Note: Post formats is deprecated, please see /sites/$id/post-formats/',
+ 'plan' => '(array) Details of the current plan for this site.',
'updates' => '(array) An array of available updates for plugins, themes, wordpress, and languages.',
'jetpack_modules' => '(array) A list of active Jetpack modules.',
'meta' => '(object) Meta data',
);
+
function callback( $path = '', $blog_id = 0 ) {
add_filter( 'sites_site_format', array( $this, 'site_format' ) );
return parent::callback( $path, $blog_id );
}
- //V1.2 renames lang to locale
- protected function process_locale( $key, $is_user_logged_in ) {
- if ( $is_user_logged_in && 'locale' == $key ) {
- if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
- if ( ! is_jetpack_site() ) {
- return (string) get_blog_lang_code();
- }
- }
- }
- return false;
- }
-
public function site_format( $format ) {
return self::$site_format;
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-term-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-term-endpoint.php
new file mode 100644
index 00000000..fcb9a6f7
--- /dev/null
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-get-term-endpoint.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * WARNING: This file is distributed verbatim in Jetpack.
+ * There should be nothing WordPress.com specific in this file.
+ *
+ * @hide-in-jetpack
+ */
+
+class WPCOM_JSON_API_Get_Term_Endpoint extends WPCOM_JSON_API_Endpoint {
+ // /sites/%s/taxonomies/%s/terms/slug:%s -> $blog_id, $taxonomy, $slug
+ function callback( $path = '', $blog_id = 0, $taxonomy = 'category', $slug = 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 ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $this->load_theme_functions();
+ }
+
+ $taxonomy_meta = get_taxonomy( $taxonomy );
+ if ( false === $taxonomy_meta || ( ! $taxonomy_meta->public &&
+ ! current_user_can( $taxonomy_meta->cap->assign_terms ) ) ) {
+ return new WP_Error( 'invalid_taxonomy', 'The taxonomy does not exist', 400 );
+ }
+
+ $args = $this->query_args();
+ $term = $this->get_taxonomy( $slug, $taxonomy, $args['context'] );
+ if ( ! $term || is_wp_error( $term ) ) {
+ return $term;
+ }
+
+ /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
+ do_action( 'wpcom_json_api_objects', 'terms' );
+
+ return $term;
+ }
+}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-comments-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-comments-endpoint.php
index 9b80601d..cdb0d466 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-comments-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-comments-endpoint.php
@@ -229,7 +229,9 @@ class WPCOM_JSON_API_List_Comments_Endpoint extends WPCOM_JSON_API_Comment_Endpo
if ( $args['hierarchical'] ) {
$walker = new WPCOM_JSON_API_List_Comments_Walker;
$comment_ids = $walker->paged_walk( $comments, get_option( 'thread_comments_depth', -1 ), isset( $args['page'] ) ? $args['page'] : 1 , $args['number'] );
- $comments = array_map( 'get_comment', $comment_ids );
+ if ( ! empty( $comment_ids ) ) {
+ $comments = array_map( 'get_comment', $comment_ids );
+ }
}
$return = array();
@@ -244,10 +246,12 @@ class WPCOM_JSON_API_List_Comments_Endpoint extends WPCOM_JSON_API_Comment_Endpo
break;
case 'comments' :
$return_comments = array();
- foreach ( $comments as $comment ) {
- $the_comment = $this->get_comment( $comment->comment_ID, $args['context'] );
- if ( $the_comment && !is_wp_error( $the_comment ) ) {
- $return_comments[] = $the_comment;
+ if ( ! empty( $comments ) ) {
+ foreach ( $comments as $comment ) {
+ $the_comment = $this->get_comment( $comment->comment_ID, $args['context'] );
+ if ( $the_comment && !is_wp_error( $the_comment ) ) {
+ $return_comments[] = $the_comment;
+ }
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-embeds-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-embeds-endpoint.php
index e5cfd7f3..35efd1d3 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-embeds-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-embeds-endpoint.php
@@ -36,4 +36,4 @@ class WPCOM_JSON_API_List_Embeds_Endpoint extends WPCOM_JSON_API_Endpoint {
return $output;
}
-}
+} \ No newline at end of file
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-1-endpoint.php
index a5b2354c..fc2e479a 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-media-v1-1-endpoint.php
@@ -40,7 +40,6 @@ class WPCOM_JSON_API_List_Media_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint {
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_parent' => isset( $args['post_ID'] ) ? $args['post_ID'] : null,
- 'offset' => isset( $args['offset'] ) ? $args['offset'] : null,
'posts_per_page' => $args['number'],
'post_mime_type' => isset( $args['mime_type'] ) ? $args['mime_type'] : null,
'order' => isset( $args['order'] ) ? $args['order'] : 'DESC',
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
new file mode 100644
index 00000000..be037134
--- /dev/null
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-post-type-taxonomies-endpoint.php
@@ -0,0 +1,71 @@
+<?php
+/*
+ * WARNING: This file is distributed verbatim in Jetpack.
+ * There should be nothing WordPress.com specific in this file.
+ *
+ * @hide-in-jetpack
+ */
+
+class WPCOM_JSON_API_List_Post_Type_Taxonomies_Endpoint extends WPCOM_JSON_API_Endpoint {
+ static $taxonomy_keys_to_include = array(
+ 'name' => 'name',
+ 'label' => 'label',
+ 'labels' => 'labels',
+ 'description' => 'description',
+ 'hierarchical' => 'hierarchical',
+ 'public' => 'public',
+ 'cap' => 'capabilities',
+ );
+
+ // /sites/%s/post-types/%s/taxonomies -> $blog_id, $post_type
+ function callback( $path = '', $blog_id = 0, $post_type = 'post' ) {
+ $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 ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $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();
+ }
+
+ $args = $this->query_args();
+
+ $post_type_object = get_post_type_object( $post_type );
+ if ( ! $post_type_object || ( ! $post_type_object->publicly_queryable && (
+ ! current_user_can( $post_type_object->cap->edit_posts ) ) ) ) {
+ return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
+ }
+
+ // Get a list of available taxonomies
+ $taxonomy_objects = get_object_taxonomies( $post_type, 'objects' );
+
+ // Construct array of formatted objects
+ $formatted_taxonomy_objects = array();
+ foreach ( $taxonomy_objects as $taxonomy_object ) {
+ // Omit private taxonomies unless user has assign capability
+ if ( ! $taxonomy_object->public && ! current_user_can( $taxonomy_object->cap->assign_terms ) ) {
+ continue;
+ }
+
+ // Include only the desired keys in the response
+ $formatted_taxonomy_object = array();
+ foreach ( self::$taxonomy_keys_to_include as $key => $value ) {
+ $formatted_taxonomy_object[ $value ] = $taxonomy_object->{ $key };
+ }
+
+ $formatted_taxonomy_objects[] = $formatted_taxonomy_object;
+ }
+
+ return array(
+ 'found' => count( $formatted_taxonomy_objects ),
+ 'taxonomies' => $formatted_taxonomy_objects,
+ );
+ }
+}
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 e7521abe..c18719f0 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
@@ -8,6 +8,7 @@ class WPCOM_JSON_API_List_Post_Types_Endpoint extends WPCOM_JSON_API_Endpoint {
'description' => 'description',
'map_meta_cap' => 'map_meta_cap',
'cap' => 'capabilities',
+ 'hierarchical' => 'hierarchical',
);
// /sites/%s/post-types -> $blog_id
@@ -23,9 +24,15 @@ class WPCOM_JSON_API_List_Post_Types_Endpoint extends WPCOM_JSON_API_Endpoint {
$args = $this->query_args();
- // API localization occurs after the initial post types have been
- // registered, so re-register if localizing response
+ /**
+ * Whether API responses should be returned in a custom locale. False
+ * for Jetpack; may be true for WP.com requests.
+ *
+ * @since 3.9.2
+ */
if ( apply_filters( 'rest_api_localize_response', false ) ) {
+ // API localization occurs after the initial post types have been
+ // registered, so re-register if localizing response
create_initial_post_types();
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-endpoint.php
index ca1c5a10..1ab369f0 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-endpoint.php
@@ -104,7 +104,7 @@ class WPCOM_JSON_API_List_Posts_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
if ( isset( $args['meta_key'] ) ) {
$show = false;
- if ( $this->is_metadata_public( $args['meta_key'] ) )
+ if ( WPCOM_JSON_API_Metadata::is_public( $args['meta_key'] ) )
$show = true;
if ( current_user_can( 'edit_post_meta', $query['post_type'], $args['meta_key'] ) )
$show = true;
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php
index 1f009365..61953a1f 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-posts-v1-1-endpoint.php
@@ -115,7 +115,7 @@ class WPCOM_JSON_API_List_Posts_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_E
if ( isset( $args['meta_key'] ) ) {
$show = false;
- if ( $this->is_metadata_public( $args['meta_key'] ) )
+ if ( WPCOM_JSON_API_Metadata::is_public( $args['meta_key'] ) )
$show = true;
if ( current_user_can( 'edit_post_meta', $query['post_type'], $args['meta_key'] ) )
$show = true;
@@ -296,7 +296,7 @@ class WPCOM_JSON_API_List_Posts_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_E
if ( ! is_array( $args['type'] ) ) {
$return[$key] = (object) array(
'links' => (object) array(
- 'counts' => (string) $this->get_site_link( $blog_id, 'post-counts/' . $args['type'] ),
+ 'counts' => (string) $this->links->get_site_link( $blog_id, 'post-counts/' . $args['type'] ),
)
);
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-shortcodes-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-shortcodes-endpoint.php
index 28a42350..9b2fc1aa 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-shortcodes-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-shortcodes-endpoint.php
@@ -19,9 +19,9 @@ class WPCOM_JSON_API_List_Shortcodes_Endpoint extends WPCOM_JSON_API_Endpoint {
foreach ( $shortcode_tags as $tag => $class ) {
if ( '__return_false' == $class )
continue;
- $output['shortcodes'][] = $tag;
+ $output['shortcodes'][] = $tag;
}
return $output;
}
-}
+} \ No newline at end of file
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-terms-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-terms-endpoint.php
new file mode 100644
index 00000000..c015e34a
--- /dev/null
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-terms-endpoint.php
@@ -0,0 +1,87 @@
+<?php
+/*
+ * WARNING: This file is distributed verbatim in Jetpack.
+ * There should be nothing WordPress.com specific in this file.
+ *
+ * @hide-in-jetpack
+ */
+
+class WPCOM_JSON_API_List_Terms_Endpoint extends WPCOM_JSON_API_Endpoint {
+ // /sites/%s/taxonomies/%s/terms -> $blog_id, $taxonomy
+ function callback( $path = '', $blog_id = 0, $taxonomy = 'category' ) {
+ $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 ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $this->load_theme_functions();
+ }
+
+ $taxonomy_meta = get_taxonomy( $taxonomy );
+ if ( false === $taxonomy_meta || ( ! $taxonomy_meta->public &&
+ ! current_user_can( $taxonomy_meta->cap->assign_terms ) ) ) {
+ return new WP_Error( 'invalid_taxonomy', 'The taxonomy does not exist', 400 );
+ }
+
+ $args = $this->query_args();
+ $args = $this->process_args( $args );
+
+ $formatted_terms = $this->get_formatted_terms( $taxonomy, $args );
+
+ if ( ! empty( $formatted_terms ) ) {
+ /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
+ do_action( 'wpcom_json_api_objects', 'terms', count( $formatted_terms ) );
+ }
+
+ return array(
+ 'found' => (int) $this->get_found( $taxonomy, $args ),
+ 'terms' => (array) $formatted_terms
+ );
+ }
+
+ function process_args( $args ) {
+ $args['get'] = 'all';
+
+ if ( $args['number'] < 1 ) {
+ $args['number'] = 100;
+ } elseif ( 1000 < $args['number'] ) {
+ return new WP_Error( 'invalid_number', 'The number parameter must be less than or equal to 1000.', 400 );
+ }
+
+ if ( isset( $args['page'] ) ) {
+ if ( $args['page'] < 1 ) {
+ $args['page'] = 1;
+ }
+
+ $args['offset'] = ( $args['page'] - 1 ) * $args['number'];
+ unset( $args['page'] );
+ }
+
+ if ( $args['offset'] < 0 ) {
+ $args['offset'] = 0;
+ }
+
+ $args['orderby'] = $args['order_by'];
+ unset( $args['order_by'] );
+
+ unset( $args['context'], $args['pretty'], $args['http_envelope'], $args['fields'] );
+ return $args;
+ }
+
+ function get_found( $taxonomy, $args ) {
+ unset( $args['offset'] );
+ return wp_count_terms( $taxonomy, $args );
+ }
+
+ function get_formatted_terms( $taxonomy, $args ) {
+ $terms = get_terms( $taxonomy, $args );
+
+ $formatted_terms = array();
+ foreach ( $terms as $term ) {
+ $formatted_terms[] = $this->format_taxonomy( $term, $taxonomy, 'display' );
+ }
+
+ return $formatted_terms;
+ }
+}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-users-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-users-endpoint.php
index 225bfa0a..fe658f99 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-users-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-list-users-endpoint.php
@@ -19,13 +19,14 @@ class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
if ( $args['number'] < 1 ) {
$args['number'] = 20;
- } elseif ( 100 < $args['number'] ) {
- return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 100.', 400 );
+ } elseif ( 1000 < $args['number'] ) {
+ return new WP_Error( 'invalid_number', 'The NUMBER parameter must be less than or equal to 1000.', 400 );
}
if ( $authors_only ) {
- if ( empty( $args['type'] ) )
+ if ( empty( $args['type'] ) ) {
$args['type'] = 'post';
+ }
if ( ! $this->is_post_type_allowed( $args['type'] ) ) {
return new WP_Error( 'unknown_post_type', 'Unknown post type', 404 );
@@ -47,8 +48,9 @@ class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
'fields' => 'ID',
);
- if ( $authors_only )
+ if ( $authors_only ) {
$query['who'] = 'authors';
+ }
if ( ! empty( $args['search'] ) ) {
$query['search'] = $args['search'];
@@ -72,7 +74,7 @@ class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
foreach ( array_keys( $this->response_format ) as $key ) {
switch ( $key ) {
case 'found' :
- $return[$key] = (int) $user_query->get_total();
+ $return[ $key ] = (int) $user_query->get_total();
break;
case 'users' :
$users = array();
@@ -89,7 +91,7 @@ class WPCOM_JSON_API_List_Users_Endpoint extends WPCOM_JSON_API_Endpoint {
}
}
- $return[$key] = $users;
+ $return[ $key ] = $users;
break;
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php
index c77ce8d3..fe61e71a 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php
@@ -454,11 +454,14 @@ class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator {
protected function location_name_exists( $location_name ) {
$widget_location_names = wp_list_pluck( WPCOM_JSON_API_Menus_Widgets::get(), 'name' );
+ $existing_locations = get_nav_menu_locations();
+
if ( ! is_array( get_registered_nav_menus() ) ) {
return false;
}
return array_key_exists( $location_name, get_registered_nav_menus() ) ||
+ array_key_exists( $location_name, $existing_locations ) ||
in_array( $location_name, $widget_location_names );
}
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 9dc1a1fa..d28d9697 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
@@ -272,7 +272,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
$response[$key] = (object) array(
'ID' => (int) $parent->ID,
'type' => (string) $parent->post_type,
- 'link' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $parent->ID ),
+ 'link' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $parent->ID ),
'title' => $parent_title,
);
} else {
@@ -443,7 +443,7 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
foreach ( (array) has_meta( $post_id ) as $meta ) {
// Don't expose protected fields.
$show = false;
- if ( $this->is_metadata_public( $meta['meta_key'] ) )
+ if ( WPCOM_JSON_API_Metadata::is_public( $meta['meta_key'] ) )
$show = true;
if ( current_user_can( 'edit_post_meta', $post_id , $meta['meta_key'] ) )
$show = true;
@@ -467,13 +467,11 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
case 'meta' :
$response[$key] = (object) array(
'links' => (object) array(
- 'self' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ),
- 'help' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'help' ),
- 'site' => (string) $this->get_site_link( $this->api->get_blog_id_for_output() ),
-// 'author' => (string) $this->get_user_link( $post->post_author ),
-// 'via' => (string) $this->get_post_link( $reblog_origin_blog_id, $reblog_origin_post_id ),
- 'replies' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'replies/' ),
- 'likes' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'likes/' ),
+ 'self' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ),
+ 'help' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'help' ),
+ 'site' => (string) $this->links->get_site_link( $this->api->get_blog_id_for_output() ),
+ 'replies' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'replies/' ),
+ 'likes' => (string) $this->links->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'likes/' ),
),
);
break;
@@ -665,7 +663,11 @@ abstract class WPCOM_JSON_API_Post_Endpoint extends WPCOM_JSON_API_Endpoint {
return new WP_Error( 'invalid_post', 'Invalid post', 400 );
}
- $posts = get_posts( array( 'name' => $name ) );
+ $posts = get_posts( array(
+ 'name' => $name,
+ 'numberposts' => 1,
+ 'post_type' => $this->_get_whitelisted_post_types(),
+ ) );
if ( ! $posts || ! isset( $posts[0]->ID ) || ! $posts[0]->ID ) {
$page = get_page_by_path( $name );
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 30783d14..93dade64 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
@@ -43,6 +43,7 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
'menu_order' => '(int) (Pages Only) The order pages should appear in.',
'page_template' => '(string) (Pages Only) The page template this page is using.',
'publicize_URLs' => '(array:URL) Array of Twitter and Facebook URLs published by this post.',
+ 'terms' => '(object) Hash of taxonomy names mapping to a hash of terms keyed by term name.',
'tags' => '(object:tag) Hash of tags (keyed by tag name) applied to the post.',
'categories' => '(object:category) Hash of categories (keyed by category name) applied to the post.',
'attachments' => '(object:attachment) Hash of post attachments (keyed by attachment ID). Returns the most recent 20 attachments. Use the `/sites/$site/media` endpoint to query the attachments beyond the default of 20 that are returned here.',
@@ -66,31 +67,6 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
parent::__construct( $args );
}
- function is_metadata_public( $key ) {
- if ( empty( $key ) )
- return false;
-
- // Default whitelisted meta keys.
- $whitelisted_meta = array( '_thumbnail_id' );
-
- // whitelist of metadata that can be accessed
- /** This filter is documented in json-endpoints/class.wpcom-json-api-post-endpoint.php */
- if ( in_array( $key, apply_filters( 'rest_api_allowed_public_metadata', $whitelisted_meta ) ) )
- return true;
-
- if ( 0 === strpos( $key, 'geo_' ) )
- return true;
-
- if ( 0 === strpos( $key, '_wpas_' ) )
- return true;
-
- return false;
- }
-
- function the_password_form() {
- return __( 'This post is password protected.', 'jetpack' );
- }
-
/**
* Get a post by a specified field and value
*
@@ -100,15 +76,14 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
* @return array Post
**/
function get_post_by( $field, $field_value, $context = 'display' ) {
- global $blog_id;
- /** This filter is documented in class.json-api-endpoints.php */
- $is_jetpack = true === apply_filters( 'is_jetpack_site', false, $blog_id );
+ // validate input
+ if ( ! in_array( $field, array( 'ID', 'name' ) ) ) {
+ return new WP_Error( 'invalid_field', 'Invalid API FIELD', 400 );
+ }
- if ( defined( 'GEO_LOCATION__CLASS' ) && class_exists( GEO_LOCATION__CLASS ) ) {
- $geo = call_user_func( array( GEO_LOCATION__CLASS, 'init' ) );
- } else {
- $geo = false;
+ if ( ! in_array( $context, array( 'display', 'edit' ) ) ) {
+ return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
}
if ( 'display' === $context ) {
@@ -123,415 +98,178 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
add_shortcode( 'gallery', array( &$this, 'win8_gallery_shortcode' ) );
}
- switch ( $field ) {
- case 'name' :
- $post_id = $this->get_post_id_by_name( $field_value );
- if ( is_wp_error( $post_id ) ) {
- return $post_id;
- }
- break;
- default :
- $post_id = (int) $field_value;
- break;
- }
+ // fetch SAL post
+ $post = $this->get_sal_post_by( $field, $field_value, $context );
- $post = get_post( $post_id, OBJECT, $context );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
- if ( !$post || is_wp_error( $post ) ) {
- return new WP_Error( 'unknown_post', 'Unknown post', 404 );
- }
+ $GLOBALS['post'] = $post;
- if ( ! $this->is_post_type_allowed( $post->post_type ) && ( ! function_exists( 'is_post_freshly_pressed' ) || ! is_post_freshly_pressed( $post->ID ) ) ) {
- return new WP_Error( 'unknown_post', 'Unknown post', 404 );
+ // TODO: not sure where this one should go
+ if ( 'display' === $context ) {
+ setup_postdata( $post );
}
- // Permissions
- $capabilities = $this->get_current_user_capabilities( $post );
+ $response = $this->render_response_keys( $post, $context, array_keys( $this->post_object_format ) );
- switch ( $context ) {
- case 'edit' :
- if ( ! $capabilities['edit_post'] ) {
- return new WP_Error( 'unauthorized', 'User cannot edit post', 403 );
- }
- break;
- case 'display' :
- break;
- default :
- return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
- }
+ unset( $GLOBALS['post'] );
- $can_view = $this->user_can_view_post( $post->ID );
- if ( !$can_view || is_wp_error( $can_view ) ) {
- return $can_view;
- }
+ return $response;
+ }
- $GLOBALS['post'] = $post;
+ protected function get_sal_post_by( $field, $field_value, $context ) {
+ global $blog_id;
- if ( 'display' === $context ) {
- setup_postdata( $post );
- }
+ $site = $this->get_platform()->get_site( $blog_id );
+
+ $post = ( $field === 'name' ) ?
+ $site->get_post_by_name( $field_value, $context ) :
+ $site->get_post_by_id( $field_value, $context );
- $response = array();
- foreach ( array_keys( $this->post_object_format ) as $key ) {
+ return $post;
+ }
+
+ private function render_response_keys( $post, $context, $keys ) {
+ foreach ( $keys as $key ) {
switch ( $key ) {
case 'ID' :
// explicitly cast all output
$response[$key] = (int) $post->ID;
break;
case 'site_ID' :
- $response[$key] = (int) $this->api->get_blog_id_for_output();
+ $response[$key] = $post->site->get_id();
break;
case 'author' :
- $response[$key] = (object) $this->get_author( $post, 'edit' === $context && $capabilities['edit_post'] );
+ $response[$key] = $post->get_author();
break;
case 'date' :
- $response[$key] = (string) $this->format_date( $post->post_date_gmt, $post->post_date );
+ $response[$key] = $post->get_date();
break;
case 'modified' :
- $response[$key] = (string) $this->format_date( $post->post_modified_gmt, $post->post_modified );
+ $response[$key] = $post->get_modified_date();
break;
case 'title' :
- if ( 'display' === $context ) {
- $response[$key] = (string) get_the_title( $post->ID );
- } else {
- $response[$key] = (string) htmlspecialchars_decode( $post->post_title, ENT_QUOTES );
- }
+ $response[$key] = $post->get_title();
break;
case 'URL' :
- if ( 'revision' === $post->post_type ) {
- $response[$key] = (string) esc_url_raw( get_permalink( $post->post_parent ) );
- } else {
- $response[$key] = (string) esc_url_raw( get_permalink( $post->ID ) );
- }
+ $response[$key] = $post->get_url();
break;
case 'short_URL' :
- $response[$key] = (string) esc_url_raw( wp_get_shortlink( $post->ID ) );
+ $response[$key] = $post->get_shortlink();
break;
case 'content' :
- if ( 'display' === $context ) {
- add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
- $response[$key] = (string) $this->get_the_post_content_for_display();
- remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
- } else {
- $response[$key] = (string) $post->post_content;
- }
+ $response[$key] = $post->get_content();
break;
case 'excerpt' :
- if ( 'display' === $context ) {
- add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
- ob_start();
- the_excerpt();
- $response[$key] = (string) ob_get_clean();
- remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
- } else {
- $response[$key] = htmlspecialchars_decode( (string) $post->post_excerpt, ENT_QUOTES );
- }
+ $response[$key] = $post->get_excerpt();
break;
case 'status' :
- $response[$key] = (string) get_post_status( $post->ID );
+ $response[$key] = $post->get_status();
break;
case 'sticky' :
- $response[$key] = (bool) is_sticky( $post->ID );
+ $response[$key] = $post->is_sticky();
break;
case 'slug' :
- $response[$key] = (string) $post->post_name;
+ $response[$key] = $post->get_slug();
break;
case 'guid' :
- $response[$key] = (string) $post->guid;
+ $response[$key] = $post->get_guid();
break;
case 'password' :
- $response[$key] = (string) $post->post_password;
- if ( 'edit' === $context ) {
- $response[$key] = htmlspecialchars_decode( (string) $response[$key], ENT_QUOTES );
- }
+ $response[$key] = $post->get_password();
break;
case 'parent' : // (object|false)
- if ( $post->post_parent ) {
- $parent = get_post( $post->post_parent );
- if ( 'display' === $context ) {
- $parent_title = (string) get_the_title( $parent->ID );
- } else {
- $parent_title = (string) htmlspecialchars_decode( $post->post_title, ENT_QUOTES );
- }
- $response[$key] = (object) array(
- 'ID' => (int) $parent->ID,
- 'type' => (string) $parent->post_type,
- 'link' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $parent->ID ),
- 'title' => $parent_title,
- );
- } else {
- $response[$key] = false;
- }
+ $response[$key] = $post->get_parent();
break;
case 'type' :
- $response[$key] = (string) $post->post_type;
+ $response[$key] = $post->get_type();
break;
case 'discussion' :
- $response[$key] = array(
- 'comments_open' => (bool) comments_open( $post->ID ),
- 'comment_status' => (string) $post->comment_status,
- 'pings_open' => (bool) pings_open( $post->ID ),
- 'ping_status' => (string) $post->ping_status,
- 'comment_count' => (int) $post->comment_count,
- );
+ $response[$key] = $post->get_discussion();
break;
case 'likes_enabled' :
- /** This filter is documented in modules/likes.php */
- $sitewide_likes_enabled = (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
- $post_likes_switched = (bool) get_post_meta( $post->ID, 'switch_like_status', true );
- $post_likes_enabled = $sitewide_likes_enabled;
- if ( $post_likes_switched ) {
- $post_likes_enabled = ! $post_likes_enabled;
- }
- $response[$key] = (bool) $post_likes_enabled;
+ $response[$key] = $post->is_likes_enabled();
break;
case 'sharing_enabled' :
- $show = true;
- /** This filter is documented in modules/sharedaddy/sharing-service.php */
- $show = apply_filters( 'sharing_show', $show, $post );
-
- $switched_status = get_post_meta( $post->ID, 'sharing_disabled', false );
-
- if ( !empty( $switched_status ) )
- $show = false;
- $response[$key] = (bool) $show;
+ $response[$key] = $post->is_sharing_enabled();
break;
case 'like_count' :
- $response[$key] = (int) $this->api->post_like_count( $blog_id, $post->ID );
+ $response[$key] = $post->get_like_count();
break;
case 'i_like' :
- $response[$key] = (bool) $this->api->is_liked( $blog_id, $post->ID );
+ $response[$key] = $post->is_liked();
break;
case 'is_reblogged':
- $response[$key] = (bool) $this->api->is_reblogged( $blog_id, $post->ID );
+ $response[$key] = $post->is_reblogged();
break;
case 'is_following':
- $response[$key] = (bool) $this->api->is_following( $blog_id );
+ $response[$key] = $post->is_following();
break;
case 'global_ID':
- $response[$key] = (string) $this->api->add_global_ID( $blog_id, $post->ID );
+ $response[$key] = $post->get_global_id();
break;
case 'featured_image' :
- if ( $is_jetpack && ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
- $response[ $key ] = get_post_meta( $post->ID, '_jetpack_featured_image', true );
- } else {
- $image_attributes = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
- if ( is_array( $image_attributes ) && isset( $image_attributes[0] ) ) {
- $response[ $key ] = (string) $image_attributes[0];
- } else {
- $response[ $key ] = '';
- }
- }
+ $response[$key] = $post->get_featured_image();
break;
case 'post_thumbnail' :
- $response[$key] = null;
-
- $thumb_id = get_post_thumbnail_id( $post->ID );
- if ( ! empty( $thumb_id ) ) {
- $attachment = get_post( $thumb_id );
- if ( ! empty( $attachment ) )
- $featured_image_object = $this->get_attachment( $attachment );
-
- if ( ! empty( $featured_image_object ) ) {
- $response[$key] = (object) $featured_image_object;
- }
- }
+ $response[$key] = $post->get_post_thumbnail();
break;
case 'format' :
- $response[$key] = (string) get_post_format( $post->ID );
- if ( !$response[$key] ) {
- $response[$key] = 'standard';
- }
+ $response[$key] = $post->get_format();
break;
case 'geo' : // (object|false)
- if ( !$geo ) {
- $response[$key] = false;
- } else {
- $geo_data = $geo->get_geo( 'post', $post->ID );
- $response[$key] = false;
- if ( $geo_data ) {
- $geo_data = array_intersect_key( $geo_data, array( 'latitude' => true, 'longitude' => true, 'address' => true, 'public' => true ) );
- if ( $geo_data ) {
- $response[$key] = (object) array(
- 'latitude' => isset( $geo_data['latitude'] ) ? (float) $geo_data['latitude'] : 0,
- 'longitude' => isset( $geo_data['longitude'] ) ? (float) $geo_data['longitude'] : 0,
- 'address' => isset( $geo_data['address'] ) ? (string) $geo_data['address'] : '',
- );
- } else {
- $response[$key] = false;
- }
- // Private
- if ( !isset( $geo_data['public'] ) || !$geo_data['public'] ) {
- if ( 'edit' !== $context || ! $capabilities['edit_post'] ) {
- // user can't access
- $response[$key] = false;
- }
- }
- }
- }
+ $response[$key] = $post->get_geo();
break;
case 'menu_order':
- $response[$key] = (int) $post->menu_order;
+ $response[$key] = $post->get_menu_order();
break;
case 'page_template':
- $response[$key] = (string) get_post_meta( $post->ID, '_wp_page_template', true );
+ $response[$key] = $post->get_page_template();
break;
case 'publicize_URLs' :
- $publicize_URLs = array();
- $publicize = get_post_meta( $post->ID, 'publicize_results', true );
- if ( $publicize ) {
- foreach ( $publicize as $service => $data ) {
- switch ( $service ) {
- case 'twitter' :
- foreach ( $data as $datum ) {
- $publicize_URLs[] = esc_url_raw( "https://twitter.com/{$datum['user_id']}/status/{$datum['post_id']}" );
- }
- break;
- case 'fb' :
- foreach ( $data as $datum ) {
- $publicize_URLs[] = esc_url_raw( "https://www.facebook.com/permalink.php?story_fbid={$datum['post_id']}&id={$datum['user_id']}" );
- }
- break;
- }
- }
- }
- $response[$key] = (array) $publicize_URLs;
+ $response[$key] = $post->get_publicize_urls();
+ break;
+ case 'terms':
+ $response[$key] = $post->get_terms();
break;
case 'tags' :
- $response[$key] = array();
- $terms = wp_get_post_tags( $post->ID );
- foreach ( $terms as $term ) {
- if ( !empty( $term->name ) ) {
- $response[$key][$term->name] = $this->format_taxonomy( $term, 'post_tag', 'display' );
- }
- }
- $response[$key] = (object) $response[$key];
+ $response[$key] = $post->get_tags();
break;
case 'categories':
- $response[$key] = array();
- $terms = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'all' ) );
- foreach ( $terms as $term ) {
- if ( !empty( $term->name ) ) {
- $response[$key][$term->name] = $this->format_taxonomy( $term, 'category', 'display' );
- }
- }
- $response[$key] = (object) $response[$key];
+ $response[$key] = $post->get_categories();
break;
case 'attachments':
- $response[$key] = array();
- $_attachments = new WP_Query( array( 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'posts_per_page' => '20' ) );
- foreach ( $_attachments->posts as $attachment ) {
- $response[$key][$attachment->ID] = $this->get_media_item_v1_1( $attachment->ID );
- }
- $response['attachment_count'] = $_attachments->found_posts;
- $response[$key] = (object) $response[$key];
+ list( $attachments, $attachment_count ) = $post->get_attachments_and_count();
+ $response[$key] = $attachments;
+ $response['attachment_count'] = $attachment_count;
break;
case 'metadata' : // (array|false)
- $metadata = array();
- foreach ( (array) has_meta( $post_id ) as $meta ) {
- // Don't expose protected fields.
- $show = false;
- if ( $this->is_metadata_public( $meta['meta_key'] ) )
- $show = true;
- if ( current_user_can( 'edit_post_meta', $post_id , $meta['meta_key'] ) )
- $show = true;
-
- if ( !$show )
- continue;
-
- $metadata[] = array(
- 'id' => $meta['meta_id'],
- 'key' => $meta['meta_key'],
- 'value' => maybe_unserialize( $meta['meta_value'] ),
- );
- }
-
- if ( ! empty( $metadata ) ) {
- $response[$key] = $metadata;
- } else {
- $response[$key] = false;
- }
+ $response[$key] = $post->get_metadata();
break;
case 'meta' :
- $response[$key] = (object) array(
- 'links' => (object) array(
- 'self' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ),
- 'help' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'help' ),
- 'site' => (string) $this->get_site_link( $this->api->get_blog_id_for_output() ),
-// 'author' => (string) $this->get_user_link( $post->post_author ),
-// 'via' => (string) $this->get_post_link( $reblog_origin_blog_id, $reblog_origin_post_id ),
- 'replies' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'replies/' ),
- 'likes' => (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID, 'likes/' ),
- ),
- );
-
- // add autosave link if a more recent autosave exists
- if ( 'edit' === $context ) {
- $autosave = wp_get_post_autosave( $post_id );
- if ( $autosave && $autosave->post_modified > $post->post_modified )
- $response[$key]->links->autosave = (string) $this->get_post_link( $this->api->get_blog_id_for_output(), $post->ID ) . '/autosave';
- }
-
+ $response[$key] = $post->get_meta();
break;
case 'capabilities' :
- $response[$key] = $capabilities;
+ $response[$key] = $post->get_current_user_capabilities();
break;
case 'revisions' :
- if ( 'edit' !== $context ) {
- continue;
- }
- $revisions = array();
- $post_revisions = wp_get_post_revisions( $post->ID );
-
- foreach ( $post_revisions as $_post ) {
- $revisions[] = $_post->ID;
+ $revisions = $post->get_revisions();
+ if ( $revisions ) {
+ $response[$key] = $revisions;
}
-
- $response[$key] = $revisions;
-
break;
case 'other_URLs' :
- $other_urls = array();
-
- if ( 'publish' !== $post->post_status ) {
- $other_urls = $this->get_post_permalink_suggestions( $post->ID, $post->post_title );
- }
-
- $response[$key] = (object) $other_urls;
+ $response[$key] = $post->get_other_urls();
break;
}
}
- // WPCOM_JSON_API_Post_Endpoint::find_featured_worthy_media( $post );
- // $response['featured_media'] = self::find_featured_media( $response );
-
- unset( $GLOBALS['post'] );
return $response;
}
- // No Blog ID parameter. No Post ID parameter. Depends on globals.
- // Expects setup_postdata() to already have been run
- function get_the_post_content_for_display() {
- global $pages, $page;
-
- $old_pages = $pages;
- $old_page = $page;
-
- $content = join( "\n\n", $pages );
- $content = preg_replace( '/<!--more(.*?)?-->/', '', $content );
- $pages = array( $content );
- $page = 1;
-
- ob_start();
- the_content();
- $return = ob_get_clean();
-
- $pages = $old_pages;
- $page = $old_page;
-
- return $return;
- }
-
+ // TODO: factor this out
function get_blog_post( $blog_id, $post_id, $context = 'display' ) {
$blog_id = $this->api->get_blog_id( $blog_id );
if ( !$blog_id || is_wp_error( $blog_id ) ) {
@@ -543,26 +281,6 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
return $post;
}
- /**
- * Supporting featured media in post endpoints. Currently on for wpcom blogs
- * since it's calling WPCOM_JSON_API_Read_Endpoint methods which presently
- * rely on wpcom specific functionality.
- *
- * @param WP_Post $post
- * @return object list of featured media
- */
- public static function find_featured_media( &$post ) {
-
- if ( class_exists( 'WPCOM_JSON_API_Read_Endpoint' ) ) {
- return WPCOM_JSON_API_Read_Endpoint::find_featured_worthy_media( (array) $post );
- } else {
- return (object) array();
- }
-
- }
-
-
-
function win8_gallery_shortcode( $attr ) {
global $post;
@@ -623,90 +341,4 @@ abstract class WPCOM_JSON_API_Post_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint
}
}
}
-
- /**
- * Returns attachment object.
- *
- * @param $attachment attachment row
- *
- * @return (object)
- */
- function get_attachment( $attachment ) {
- $metadata = wp_get_attachment_metadata( $attachment->ID );
-
- $result = array(
- 'ID' => (int) $attachment->ID,
- 'URL' => (string) wp_get_attachment_url( $attachment->ID ),
- 'guid' => (string) $attachment->guid,
- 'mime_type' => (string) $attachment->post_mime_type,
- 'width' => (int) isset( $metadata['width'] ) ? $metadata['width'] : 0,
- 'height' => (int) isset( $metadata['height'] ) ? $metadata['height'] : 0,
- );
-
- if ( isset( $metadata['duration'] ) ) {
- $result['duration'] = (int) $metadata['duration'];
- }
-
- /** This filter is documented in class.jetpack-sync.php */
- return (object) apply_filters( 'get_attachment', $result );
- }
-
- /**
- * Get post-specific user capabilities
- * @param WP_Post $post post object
- * @return array array of post-level permissions; 'publish_post', 'delete_post', 'edit_post'
- */
- function get_current_user_capabilities( $post ) {
- return array(
- 'publish_post' => current_user_can( 'publish_post', $post ),
- 'delete_post' => current_user_can( 'delete_post', $post ),
- 'edit_post' => current_user_can( 'edit_post', $post )
- );
- }
-
- /**
- * Get extra post permalink suggestions
- * @param int $postID
- * @param string $title
- * @return array array of permalink suggestions: 'permalink_URL', 'suggested_slug'
- */
- function get_post_permalink_suggestions( $postID, $title ) {
- $suggestions = array();
- list( $suggestions['permalink_URL'], $suggestions['suggested_slug'] ) = get_sample_permalink( $postID, $title );
- return $suggestions;
- }
-
- /**
- * Get post ID by name
- *
- * Attempts to match name on post title and page path
- *
- * @param string $name
- *
- * @return int|object Post ID on success, WP_Error object on failure
- **/
- protected function get_post_id_by_name( $name ) {
- $name = sanitize_title( $name );
-
- if ( ! $name ) {
- return new WP_Error( 'invalid_post', 'Invalid post', 400 );
- }
-
- $posts = get_posts( array( 'name' => $name ) );
-
- if ( ! $posts || ! isset( $posts[0]->ID ) || ! $posts[0]->ID ) {
- $page = get_page_by_path( $name );
-
- if ( ! $page ) {
- return new WP_Error( 'unknown_post', 'Unknown post', 404 );
- }
-
- $post_id = $page->ID;
- } else {
- $post_id = (int) $posts[0]->ID;
- }
-
- return $post_id;
- }
-
}
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 fe4cf85b..30c90e46 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
@@ -29,13 +29,6 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
return new WP_Error( 'invalid_embed_url', 'The embed_url parameter must be a valid URL.', 400 );
}
- // in order for oEmbed to fire in the `$wp_embed->shortcode` method, we need to set a post as the current post
- $_posts = get_posts( array( 'posts_per_page' => 1, 'suppress_filters' => false ) );
- if ( ! empty( $_posts ) ) {
- global $post;
- $post = array_shift( $_posts );
- }
-
global $wp_embed;
$render = $this->process_render( array( $this, 'do_embed' ), $embed_url );
@@ -54,8 +47,4 @@ class WPCOM_JSON_API_Render_Embed_Endpoint extends WPCOM_JSON_API_Render_Endpoin
return $return;
}
- function do_embed( $embed_url ) {
- global $wp_embed;
- return $wp_embed->shortcode( array(), $embed_url );
- }
} \ No newline at end of file
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-endpoint.php
index 273429e0..f2de7fc3 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-endpoint.php
@@ -8,7 +8,7 @@ abstract class WPCOM_JSON_API_Render_Endpoint extends WPCOM_JSON_API_Endpoint {
* props to o2's o2_Read_API::poll() function for inspiration.
*
* In short we figure out what scripts load for a "normal" page load by executing wp_head and wp_footer
- * then we render our shortcode (to both get our result, and to have the shortcode files enqueue their resources)
+ * then we render the embed/shortcode (to both get our result, and to have the shortcode files enqueue their resources)
* then we load wp_head and wp_footer again to see what new resources were added
* finally we find out the url to the source file and any extra info (like media or init js)
*/
@@ -96,7 +96,7 @@ abstract class WPCOM_JSON_API_Render_Endpoint extends WPCOM_JSON_API_Endpoint {
$media = esc_attr( $wp_styles->registered[ $handle ]->args );
}
- // add to an aray so we can return all this info
+ // add to an array so we can return all this info
$styles[ $handle ] = array (
'src' => $src,
'media' => $media,
@@ -121,4 +121,25 @@ abstract class WPCOM_JSON_API_Render_Endpoint extends WPCOM_JSON_API_Endpoint {
return $ver;
}
+ /**
+ * given a shortcode, process and return the result
+ */
+ function do_shortcode( $shortcode ) {
+ return do_shortcode( $shortcode );
+ }
+
+ /**
+ * given a one-line embed URL, process and return the result
+ */
+ function do_embed( $embed_url ) {
+ // in order for oEmbed to fire in the `$wp_embed->shortcode` method, we need to set a post as the current post
+ $_posts = get_posts( array( 'posts_per_page' => 1, 'suppress_filters' => false ) );
+ if ( ! empty( $_posts ) ) {
+ global $post;
+ $post = array_shift( $_posts );
+ }
+
+ global $wp_embed;
+ return $wp_embed->shortcode( array(), $embed_url );
+ }
} \ No newline at end of file
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-shortcode-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-shortcode-endpoint.php
index 055f84d1..8b52cfde 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-shortcode-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-render-shortcode-endpoint.php
@@ -41,10 +41,4 @@ class WPCOM_JSON_API_Render_Shortcode_Endpoint extends WPCOM_JSON_API_Render_End
return $return;
}
-
- function do_shortcode( $shortcode ) {
- $result = do_shortcode( $shortcode );
- return $result;
- }
-
} \ No newline at end of file
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-sharing-buttons-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-sharing-buttons-endpoint.php
index e497caff..2bca8261 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-sharing-buttons-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-sharing-buttons-endpoint.php
@@ -30,10 +30,10 @@ abstract class WPCOM_JSON_API_Sharing_Button_Endpoint extends WPCOM_JSON_API_End
// Status is either "disabled" or the visibility value
$response['visibility'] = $this->get_button_visibility( $button );
}
-
- if ( ! empty( $button->genericon ) ) {
+
+ if ( ! empty( $button->icon ) ) {
// Only pre-defined sharing buttons include genericon
- $response['genericon'] = $button->genericon;
+ $response['genericon'] = $button->icon;
}
if ( method_exists( $button, 'get_options' ) ) {
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 d0218514..efcc84d5 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
@@ -192,7 +192,13 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
'twitter_via' => (string) get_option( 'twitter_via' ),
'jetpack-twitter-cards-site-tag' => (string) get_option( 'jetpack-twitter-cards-site-tag' ),
'eventbrite_api_token' => $eventbrite_api_token,
- 'holidaysnow' => $holiday_snow
+ 'holidaysnow' => $holiday_snow,
+ 'gmt_offset' => get_option( 'gmt_offset' ),
+ 'timezone_string' => get_option( 'timezone_string' ),
+ 'jetpack_testimonial' => (bool) get_option( 'jetpack_testimonial', '0' ),
+ 'jetpack_testimonial_posts_per_page' => (int) get_option( 'jetpack_testimonial_posts_per_page', '10' ),
+ 'jetpack_portfolio' => (bool) get_option( 'jetpack_portfolio', '0' ),
+ 'jetpack_portfolio_posts_per_page' => (int) get_option( 'jetpack_portfolio_posts_per_page', '10' ),
);
//allow future versions of this endpoint to support additional settings keys
@@ -346,11 +352,22 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
$business_plugins->activate_plugin( 'wp-google-analytics' );
break;
+ case 'jetpack_testimonial':
+ case 'jetpack_portfolio':
case 'jetpack_comment_likes_enabled':
// settings are stored as 1|0
$coerce_value = (int) $value;
if ( update_option( $key, $coerce_value ) ) {
- $updated[ $key ] = $value;
+ $updated[ $key ] = (bool) $value;
+ }
+ break;
+
+ case 'jetpack_testimonial_posts_per_page':
+ case 'jetpack_portfolio_posts_per_page':
+ // settings are stored as numeric
+ $coerce_value = (int) $value;
+ if ( update_option( $key, $coerce_value ) ) {
+ $updated[ $key ] = $coerce_value;
}
break;
@@ -388,6 +405,24 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
}
break;
+ case 'timezone_string':
+ // Map UTC+- timezones to gmt_offsets and set timezone_string to empty
+ // https://github.com/WordPress/WordPress/blob/4.4.2/wp-admin/options.php#L175
+ if ( ! empty( $value ) && preg_match( '/^UTC[+-]/', $value ) ) {
+ $gmt_offset = preg_replace( '/UTC\+?/', '', $value );
+ if ( update_option( 'gmt_offset', $gmt_offset ) ) {
+ $updated[ 'gmt_offset' ] = $gmt_offset;
+ }
+
+ $value = '';
+ }
+
+ // Always set timezone_string either with the given value or with an
+ // empty string
+ if ( update_option( $key, $value ) ) {
+ $updated[ $key ] = $value;
+ }
+ break;
default:
//allow future versions of this endpoint to support additional settings keys
@@ -410,7 +445,6 @@ class WPCOM_JSON_API_Site_Settings_Endpoint extends WPCOM_JSON_API_Endpoint {
if ( update_option( $key, $value ) ) {
$updated[ $key ] = $value;
}
-
}
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-user-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-user-endpoint.php
index 84a83849..7a61ce12 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-user-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-user-endpoint.php
@@ -43,12 +43,9 @@ class WPCOM_JSON_API_Site_User_Endpoint extends WPCOM_JSON_API_Endpoint {
return $this->get_user( $user->ID );
} else if ( 'POST' === $this->api->method ) {
if ( ! current_user_can_for_blog( $blog_id, 'promote_users' ) ) {
- return new WP_Error( 'unauthorized', 'User cannot promote users for specified site', 403 );
+ return new WP_Error( 'unauthorized_no_promote_cap', 'User cannot promote users for specified site', 403 );
}
- if ( get_current_user_id() == $user_id ) {
- return new WP_Error( 'unauthorized', 'You cannot change your own role', 403 );
- }
- return $this->update_user( $user_id );
+ return $this->update_user( $user_id, $blog_id );
} else {
return new WP_Error( 'bad_request', 'An unsupported request method was used.' );
}
@@ -69,15 +66,25 @@ class WPCOM_JSON_API_Site_User_Endpoint extends WPCOM_JSON_API_Endpoint {
*
* @return (array)
*/
- public function update_user( $user_id ) {
+ public function update_user( $user_id, $blog_id ) {
$input = $this->input();
$user['ID'] = $user_id;
- if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
+ $is_wpcom = defined( 'IS_WPCOM' ) && IS_WPCOM;
+
+ if ( get_current_user_id() == $user_id && isset( $input['roles'] ) ) {
+ return new WP_Error( 'unauthorized', 'You cannot change your own role', 403 );
+ }
+
+ if ( $is_wpcom && $user_id !== get_current_user_id() && $user_id == wpcom_get_blog_owner( $blog_id ) ) {
+ return new WP_Error( 'unauthorized_edit_owner', 'Current user can not edit blog owner', 403 );
+ }
+
+ if ( ! $is_wpcom ) {
foreach ( $input as $key => $value ) {
if ( ! is_array( $value ) ) {
$value = trim( $value );
}
- $value = wp_unslash( $value );
+ $value = wp_unslash( $value );
switch ( $key ) {
case 'first_name':
case 'last_name':
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-invites-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-invites-endpoint.php
index 85a1ab92..689cef88 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-invites-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-invites-endpoint.php
@@ -36,7 +36,7 @@ class WPCOM_JSON_API_Update_Invites_Endpoint extends WPCOM_JSON_API_Endpoint {
'invite_key' => $invite_id,
'deleted' => $this->delete_invite(),
);
- } else {
+ } else if ( $this->api->ends_with( $this->path, '/resend' ) ) {
$returnValue = array(
'result' => $this->is_wpcom ? $this->resend_wpcom_invite() : $this->resend_self_hosted_invite()
);
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-endpoint.php
index dcf84a35..53932601 100644
--- a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-endpoint.php
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-post-endpoint.php
@@ -89,6 +89,10 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
}
+ if ( isset( $input['status'] ) && 'trash' === $input['status'] && ! current_user_can( 'delete_post', $post_id ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot delete post', 403 );
+ }
+
$post = get_post( $post_id );
$_post_type = ( ! empty( $input['type'] ) ) ? $input['type'] : $post->post_type;
$post_type = get_post_type_object( $_post_type );
@@ -559,7 +563,7 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
if ( ! empty( $meta->id ) || ! empty( $meta->previous_value ) ) {
continue;
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || $this->is_metadata_public( $meta->key ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) {
add_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -568,11 +572,11 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
if ( ! isset( $meta->value ) ) {
continue;
- } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_metadata_by_mid( 'post', $meta->id, $meta->value );
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key,$meta->value, $meta->previous_value );
- } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -685,7 +689,7 @@ class WPCOM_JSON_API_Update_Post_Endpoint extends WPCOM_JSON_API_Post_Endpoint {
return $featured_image;
}
- $featured_image_id = $this->handle_media_sideload( $featured_image, $post_id );
+ $featured_image_id = $this->handle_media_sideload( $featured_image, $post_id, 'image' );
if ( empty( $featured_image_id ) || ! is_int( $featured_image_id ) )
return false;
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 9f0bf598..d69c7d08 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
@@ -36,16 +36,21 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
remove_action( 'save_post', array( $GLOBALS['publicize_ui']->publicize, 'async_publicize_post' ), 100, 2 );
add_action( 'rest_api_inserted_post', array( $GLOBALS['publicize_ui']->publicize, 'async_publicize_post' ) );
- }
- // 'future' is an alias for 'publish' for now
- if ( 'future' === $input['status'] ) {
- $input['status'] = 'publish';
+ if ( $this->should_load_theme_functions( $post_id ) ) {
+ $this->load_theme_functions();
+ }
}
+
if ( $new ) {
$input = $this->input( true );
+ // 'future' is an alias for 'publish' for now
+ if ( 'future' === $input['status'] ) {
+ $input['status'] = 'publish';
+ }
+
if ( 'revision' === $input['type'] ) {
if ( ! isset( $input['parent'] ) ) {
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
@@ -94,6 +99,15 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
}
+ if ( isset( $input['status'] ) && 'trash' === $input['status'] && ! current_user_can( 'delete_post', $post_id ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot delete post', 403 );
+ }
+
+ // 'future' is an alias for 'publish' for now
+ if ( isset( $input['status'] ) && 'future' === $input['status'] ) {
+ $input['status'] = 'publish';
+ }
+
$post = get_post( $post_id );
$_post_type = ( ! empty( $input['type'] ) ) ? $input['type'] : $post->post_type;
$post_type = get_post_type_object( $_post_type );
@@ -149,26 +163,50 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
unset( $input['parent'] );
}
- $tax_input = array();
+ $input['terms'] = isset( $input['terms'] ) ? (array) $input['terms'] : array();
- foreach ( array( 'categories' => 'category', 'tags' => 'post_tag' ) as $key => $taxonomy ) {
- if ( ! isset( $input[ $key ] ) ) {
- continue;
+ // Convert comma-separated terms to array before attempting to
+ // merge with hardcoded taxonomies
+ foreach ( $input['terms'] as $taxonomy => $terms ) {
+ if ( is_string( $terms ) ) {
+ $input['terms'][ $taxonomy ] = explode( ',', $terms );
+ } else if ( ! is_array( $terms ) ) {
+ $input['terms'][ $taxonomy ] = array();
}
+ }
- $tax_input[ $taxonomy ] = array();
+ // For each hard-coded taxonomy, merge into terms object
+ foreach ( array( 'categories' => 'category', 'tags' => 'post_tag' ) as $taxonomy_key => $taxonomy ) {
+ if ( ! isset( $input[ $taxonomy_key ] ) ) {
+ continue;
+ }
- $is_hierarchical = is_taxonomy_hierarchical( $taxonomy );
+ if ( ! isset( $input['terms'][ $taxonomy ] ) ) {
+ $input['terms'][ $taxonomy ] = array();
+ }
- if ( is_array( $input[$key] ) ) {
- $terms = $input[$key];
- } else {
- $terms = explode( ',', $input[$key] );
+ $terms = $input[ $taxonomy_key ];
+ if ( is_string( $terms ) ) {
+ $terms = explode( ',', $terms );
+ } else if ( ! is_array( $terms ) ) {
+ continue;
}
+ $input['terms'][ $taxonomy ] = array_merge(
+ $input['terms'][ $taxonomy ],
+ $terms
+ );
+ }
+
+ $tax_input = array();
+
+ foreach ( $input['terms'] as $taxonomy => $terms ) {
+ $tax_input[ $taxonomy ] = array();
+ $is_hierarchical = is_taxonomy_hierarchical( $taxonomy );
+
foreach ( $terms as $term ) {
/**
- * `curl --data 'category[]=123'` should be interpreted as a category ID,
+ * `curl --data 'terms[category][]=123'` should be interpreted as a category ID,
* not a category whose name is '123'.
*
* Consequence: To add a category/tag whose name is '123', the client must
@@ -190,7 +228,7 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
$tax = get_taxonomy( $taxonomy );
// see https://core.trac.wordpress.org/ticket/26409
- if ( 'category' === $taxonomy && ! current_user_can( $tax->cap->edit_terms ) ) {
+ if ( $is_hierarchical && ! current_user_can( $tax->cap->edit_terms ) ) {
continue;
} else if ( ! current_user_can( $tax->cap->assign_terms ) ) {
continue;
@@ -201,10 +239,10 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
if ( ! is_wp_error( $term_info ) ) {
if ( $is_hierarchical ) {
- // Categories must be added by ID
+ // Hierarchical terms must be added by ID
$tax_input[$taxonomy][] = (int) $term_info['term_id'];
} else {
- // Tags must be added by name
+ // Non-hierarchical terms must be added by name
if ( is_int( $term ) ) {
$term = get_term( $term, $taxonomy );
$tax_input[$taxonomy][] = $term->name;
@@ -216,11 +254,11 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
}
}
- if ( isset( $input['categories'] ) && empty( $tax_input['category'] ) && 'revision' !== $post_type->name ) {
+ if ( isset( $input['terms']['category'] ) && empty( $tax_input['category'] ) && 'revision' !== $post_type->name ) {
$tax_input['category'][] = get_option( 'default_category' );
}
- unset( $input['tags'], $input['categories'] );
+ unset( $input['terms'], $input['tags'], $input['categories'] );
$insert = array();
@@ -573,7 +611,7 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
if ( ! empty( $meta->id ) || ! empty( $meta->previous_value ) ) {
continue;
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || $this->is_metadata_public( $meta->key ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) {
add_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -582,11 +620,11 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
if ( ! isset( $meta->value ) ) {
continue;
- } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_metadata_by_mid( 'post', $meta->id, $meta->value );
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key,$meta->value, $meta->previous_value );
- } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -617,7 +655,8 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
$return['media_errors'] = $media_results['errors'];
if ( 'publish' !== $post->post_status ) {
- $return['other_URLs'] = (object) $this->get_post_permalink_suggestions( $post_id, $input['title'] );
+ $sal_site = $this->get_sal_post_by( 'ID', $post_id, $args['context'] );
+ $return['other_URLs'] = (object) $sal_site->get_permalink_suggestions( $input['title'] );
}
/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
@@ -696,7 +735,7 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
return $featured_image;
}
- $featured_image_id = $this->handle_media_sideload( $featured_image, $post_id );
+ $featured_image_id = $this->handle_media_sideload( $featured_image, $post_id, 'image' );
if ( empty( $featured_image_id ) || ! is_int( $featured_image_id ) )
return false;
@@ -724,4 +763,15 @@ class WPCOM_JSON_API_Update_Post_v1_1_Endpoint extends WPCOM_JSON_API_Post_v1_1_
return $_user->ID;
}
+
+ protected function should_load_theme_functions( $post_id = null ) {
+ if ( empty( $post_id ) ) {
+ $input = $this->input( true );
+ $type = $input['type'];
+ } else {
+ $type = get_post_type( $post_id );
+ }
+
+ return ! empty( $type ) && ! in_array( $type, array( 'post', 'page', 'revision' ) );
+ }
}
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 cd7dae8b..6acef29b 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
@@ -11,16 +11,20 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
remove_action( 'save_post', array( $GLOBALS['publicize_ui']->publicize, 'async_publicize_post' ), 100, 2 );
add_action( 'rest_api_inserted_post', array( $GLOBALS['publicize_ui']->publicize, 'async_publicize_post' ) );
- }
- // 'future' is an alias for 'publish' for now
- if ( isset( $input['status'] ) && 'future' === $input['status'] ) {
- $input['status'] = 'publish';
+ if ( $this->should_load_theme_functions( $post_id ) ) {
+ $this->load_theme_functions();
+ }
}
if ( $new ) {
$input = $this->input( true );
+ // 'future' is an alias for 'publish' for now
+ if ( isset( $input['status'] ) && 'future' === $input['status'] ) {
+ $input['status'] = 'publish';
+ }
+
if ( 'revision' === $input['type'] ) {
if ( ! isset( $input['parent'] ) ) {
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
@@ -69,6 +73,15 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
}
+ if ( isset( $input['status'] ) && 'trash' === $input['status'] && ! current_user_can( 'delete_post', $post_id ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot delete post', 403 );
+ }
+
+ // 'future' is an alias for 'publish' for now
+ if ( isset( $input['status'] ) && 'future' === $input['status'] ) {
+ $input['status'] = 'publish';
+ }
+
$post = get_post( $post_id );
$_post_type = ( ! empty( $input['type'] ) ) ? $input['type'] : $post->post_type;
$post_type = get_post_type_object( $_post_type );
@@ -124,22 +137,54 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
unset( $input['parent'] );
}
- /* add taxonomies by name */
- $tax_input = array();
- foreach ( array( 'categories' => 'category', 'tags' => 'post_tag' ) as $key => $taxonomy ) {
- if ( ! isset( $input[ $key ] ) ) {
- continue;
+ foreach ( array( '', '_by_id' ) as $term_key_suffix ) {
+ $term_input_key = 'terms' . $term_key_suffix;
+ if ( isset( $input[ $term_input_key ] ) ) {
+ $input[ $term_input_key ] = (array) $input[ $term_input_key ];
+ } else {
+ $input[ $term_input_key ] = array();
}
- $tax_input[ $taxonomy ] = array();
+ // Convert comma-separated terms to array before attempting to
+ // merge with hardcoded taxonomies
+ foreach ( $input[ $term_input_key ] as $taxonomy => $terms ) {
+ if ( is_string( $terms ) ) {
+ $input[ $term_input_key ][ $taxonomy ] = explode( ',', $terms );
+ } else if ( ! is_array( $terms ) ) {
+ $input[ $term_input_key ][ $taxonomy ] = array();
+ }
+ }
- $is_hierarchical = is_taxonomy_hierarchical( $taxonomy );
+ // For each hard-coded taxonomy, merge into terms object
+ foreach ( array( 'categories' => 'category', 'tags' => 'post_tag' ) as $key_prefix => $taxonomy ) {
+ $taxonomy_key = $key_prefix . $term_key_suffix;
+ if ( ! isset( $input[ $taxonomy_key ] ) ) {
+ continue;
+ }
- if ( is_array( $input[$key] ) ) {
- $terms = $input[$key];
- } else {
- $terms = explode( ',', $input[$key] );
+ if ( ! isset( $input[ $term_input_key ][ $taxonomy ] ) ) {
+ $input[ $term_input_key ][ $taxonomy ] = array();
+ }
+
+ $terms = $input[ $taxonomy_key ];
+ if ( is_string( $terms ) ) {
+ $terms = explode( ',', $terms );
+ } else if ( ! is_array( $terms ) ) {
+ continue;
+ }
+
+ $input[ $term_input_key ][ $taxonomy ] = array_merge(
+ $input[ $term_input_key ][ $taxonomy ],
+ $terms
+ );
}
+ }
+
+ /* add terms by name */
+ $tax_input = array();
+ foreach ( $input['terms'] as $taxonomy => $terms ) {
+ $tax_input[ $taxonomy ] = array();
+ $is_hierarchical = is_taxonomy_hierarchical( $taxonomy );
foreach ( $terms as $term ) {
/**
@@ -154,7 +199,7 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
$tax = get_taxonomy( $taxonomy );
// see https://core.trac.wordpress.org/ticket/26409
- if ( 'category' === $taxonomy && ! current_user_can( $tax->cap->edit_terms ) ) {
+ if ( $is_hierarchical && ! current_user_can( $tax->cap->edit_terms ) ) {
continue;
} else if ( ! current_user_can( $tax->cap->assign_terms ) ) {
continue;
@@ -165,22 +210,18 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
if ( ! is_wp_error( $term_info ) ) {
if ( $is_hierarchical ) {
- // Categories must be added by ID
+ // Hierarchical terms must be added by ID
$tax_input[$taxonomy][] = (int) $term_info['term_id'];
} else {
- // Tags must be added by name
+ // Non-hierarchical terms must be added by name
$tax_input[$taxonomy][] = $term;
}
}
}
}
- /* add taxonomies by ID */
- foreach ( array( 'categories_by_id' => 'category', 'tags_by_id' => 'post_tag' ) as $key => $taxonomy ) {
- if ( ! isset( $input[ $key ] ) ) {
- continue;
- }
-
+ /* add terms by ID */
+ foreach ( $input['terms_by_id'] as $taxonomy => $terms ) {
// combine with any previous selections
if ( ! isset( $tax_input[ $taxonomy ] ) || ! is_array( $tax_input[ $taxonomy ] ) ) {
$tax_input[ $taxonomy ] = array();
@@ -188,12 +229,6 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
$is_hierarchical = is_taxonomy_hierarchical( $taxonomy );
- if ( is_array( $input[$key] ) ) {
- $terms = $input[$key];
- } else {
- $terms = explode( ',', $input[$key] );
- }
-
foreach ( $terms as $term ) {
$term = (string) $term; // ctype_digit compat
if ( ! ctype_digit( $term ) ) {
@@ -215,12 +250,12 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
}
}
- if ( ( isset( $input['categories'] ) || isset( $input['categories_by_id'] ) )
- && empty( $tax_input['category'] ) && 'revision' !== $post_type->name ) {
+ if ( ( isset( $input['terms']['category'] ) || isset( $input['terms_by_id']['category'] ) )
+ && empty( $tax_input['category'] ) && 'revision' !== $post_type->name ) {
$tax_input['category'][] = get_option( 'default_category' );
}
- unset( $input['tags'], $input['categories'], $input['tags_by_id'], $input['categories_by_id'] );
+ unset( $input['terms'], $input['tags'], $input['categories'], $input['terms_by_id'], $input['tags_by_id'], $input['categories_by_id'] );
$insert = array();
@@ -573,7 +608,7 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
if ( ! empty( $meta->id ) || ! empty( $meta->previous_value ) ) {
continue;
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || $this->is_metadata_public( $meta->key ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->value ) && ( current_user_can( 'add_post_meta', $post_id, $unslashed_meta_key ) ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) {
add_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -582,11 +617,11 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
if ( ! isset( $meta->value ) ) {
continue;
- } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->id ) && ! empty( $existing_meta_item->meta_key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_existing_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_metadata_by_mid( 'post', $meta->id, $meta->value );
- } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ! empty( $meta->previous_value ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key,$meta->value, $meta->previous_value );
- } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || $this->is_metadata_public( $meta->key ) ) ) {
+ } elseif ( ! empty( $meta->key ) && ( current_user_can( 'edit_post_meta', $post_id, $unslashed_meta_key ) || WPCOM_JSON_API_Metadata::is_public( $meta->key ) ) ) {
update_post_meta( $post_id, $meta->key, $meta->value );
}
@@ -616,8 +651,9 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
if ( ! empty( $media_results['errors'] ) )
$return['media_errors'] = $media_results['errors'];
- if ( ! $new && 'publish' !== $post->post_status && isset( $input['title'] ) ) {
- $return['other_URLs'] = (object) $this->get_post_permalink_suggestions( $post_id, $input['title'] );
+ if ( 'publish' !== $return['status'] && isset( $input['title'] )) {
+ $sal_site = $this->get_sal_post_by( 'ID', $post_id, $args['context'] );
+ $return['other_URLs'] = (object) $sal_site->get_permalink_suggestions( $input['title'] );
}
/** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
@@ -625,4 +661,15 @@ class WPCOM_JSON_API_Update_Post_v1_2_Endpoint extends WPCOM_JSON_API_Update_Pos
return $return;
}
+
+ protected function should_load_theme_functions( $post_id = null ) {
+ if ( empty( $post_id ) ) {
+ $input = $this->input( true );
+ $type = $input['type'];
+ } else {
+ $type = get_post_type( $post_id );
+ }
+
+ return ! empty( $type ) && ! in_array( $type, array( 'post', 'page', 'revision' ) );
+ }
}
diff --git a/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-term-endpoint.php b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-term-endpoint.php
new file mode 100644
index 00000000..499a4295
--- /dev/null
+++ b/plugins/jetpack/json-endpoints/class.wpcom-json-api-update-term-endpoint.php
@@ -0,0 +1,164 @@
+<?php
+/*
+ * WARNING: This file is distributed verbatim in Jetpack.
+ * There should be nothing WordPress.com specific in this file.
+ *
+ * @hide-in-jetpack
+ */
+
+class WPCOM_JSON_API_Update_Term_Endpoint extends WPCOM_JSON_API_Taxonomy_Endpoint {
+ // /sites/%s/taxonomies/%s/terms/new -> $blog_id, $taxonomy
+ // /sites/%s/taxonomies/%s/terms/slug:%s -> $blog_id, $taxonomy, $slug
+ // /sites/%s/taxonomies/%s/terms/slug:%s/delete -> $blog_id, $taxonomy, $slug
+ function callback( $path = '', $blog_id = 0, $taxonomy = 'category', $slug = 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 ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
+ $this->load_theme_functions();
+ }
+
+ $user = wp_get_current_user();
+ if ( ! $user || is_wp_error( $user ) || ! $user->ID ) {
+ return new WP_Error( 'authorization_required', 'An active access token must be used to manage taxonomies.', 403 );
+ }
+
+ $taxonomy_meta = get_taxonomy( $taxonomy );
+ if ( false === $taxonomy_meta || (
+ ! $taxonomy_meta->public &&
+ ! current_user_can( $taxonomy_meta->cap->manage_terms ) &&
+ ! current_user_can( $taxonomy_meta->cap->edit_terms ) &&
+ ! current_user_can( $taxonomy_meta->cap->delete_terms ) ) ) {
+ return new WP_Error( 'invalid_taxonomy', 'The taxonomy does not exist', 400 );
+ }
+
+ if ( $this->api->ends_with( $path, '/delete' ) ) {
+ return $this->delete_term( $path, $blog_id, $slug, $taxonomy );
+ } else if ( $this->api->ends_with( $path, '/new' ) ) {
+ return $this->new_term( $path, $blog_id, $taxonomy );
+ }
+
+ return $this->update_term( $path, $blog_id, $slug, $taxonomy );
+ }
+
+ // /sites/%s/taxonomies/%s/terms/new -> $blog_id, $taxonomy
+ function new_term( $path, $blog_id, $taxonomy ) {
+ $args = $this->query_args();
+ $input = $this->input();
+ if ( ! is_array( $input ) || ! $input || ! strlen( $input['name'] ) ) {
+ return new WP_Error( 'invalid_input', 'Unknown data passed', 400 );
+ }
+
+ $tax = get_taxonomy( $taxonomy );
+ if ( ! current_user_can( $tax->cap->manage_terms ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
+ }
+
+ if ( ! isset( $input['parent'] ) || ! is_taxonomy_hierarchical( $taxonomy ) ) {
+ $input['parent'] = 0;
+ }
+
+ if ( $term = get_term_by( 'name', $input['name'], $taxonomy ) ) {
+ // get_term_by is not case-sensitive, but a name with different casing is allowed
+ // also, the exact same name is allowed as long as the parents are different
+ if ( $input['name'] === $term->name && $input['parent'] === $term->parent ) {
+ return new WP_Error( 'duplicate', 'A taxonomy with that name already exists', 409 );
+ }
+ }
+
+ $data = wp_insert_term( addslashes( $input['name'] ), $taxonomy, array(
+ 'description' => addslashes( $input['description'] ),
+ 'parent' => $input['parent']
+ ) );
+
+ if ( is_wp_error( $data ) ) {
+ return $data;
+ }
+
+ $term = get_term_by( 'id', $data['term_id'], $taxonomy );
+
+ $return = $this->get_taxonomy( $term->slug, $taxonomy, $args['context'] );
+ if ( ! $return || is_wp_error( $return ) ) {
+ return $return;
+ }
+
+ /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
+ do_action( 'wpcom_json_api_objects', 'terms' );
+ return $return;
+ }
+
+ // /sites/%s/taxonomies/%s/terms/slug:%s -> $blog_id, $taxonomy, $slug
+ function update_term( $path, $blog_id, $slug, $taxonomy ) {
+ $tax = get_taxonomy( $taxonomy );
+ if ( ! current_user_can( $tax->cap->edit_terms ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
+ }
+
+ $term = get_term_by( 'slug', $slug, $taxonomy );
+ if ( ! $term || is_wp_error( $term ) ) {
+ return new WP_Error( 'unknown_taxonomy', 'Unknown taxonomy', 404 );
+ }
+
+ $args = $this->query_args();
+ $input = $this->input( false );
+ if ( ! is_array( $input ) || ! $input ) {
+ return new WP_Error( 'invalid_input', 'Invalid request input', 400 );
+ }
+
+ $update = array();
+ if ( ! empty( $input['parent'] ) || is_taxonomy_hierarchical( $taxonomy ) ) {
+ $update['parent'] = $input['parent'];
+ }
+
+ if ( ! empty( $input['description'] ) ) {
+ $update['description'] = addslashes( $input['description'] );
+ }
+
+ if ( ! empty( $input['name'] ) ) {
+ $update['name'] = addslashes( $input['name'] );
+ }
+
+ $data = wp_update_term( $term->term_id, $taxonomy, $update );
+ $term = get_term_by( 'id', $data['term_id'], $taxonomy );
+
+ $return = $this->get_taxonomy( $term->slug, $taxonomy, $args['context'] );
+ if ( ! $return || is_wp_error( $return ) ) {
+ return $return;
+ }
+
+ /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
+ do_action( 'wpcom_json_api_objects', 'terms' );
+ return $return;
+ }
+
+ // /sites/%s/taxonomies/%s/terms/slug:%s/delete -> $blog_id, $taxonomy, $slug
+ function delete_term( $path, $blog_id, $slug, $taxonomy ) {
+ $term = get_term_by( 'slug', $slug, $taxonomy );
+ $tax = get_taxonomy( $taxonomy );
+ if ( ! current_user_can( $tax->cap->delete_terms ) ) {
+ return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
+ }
+
+ if ( ! $term || is_wp_error( $term ) ) {
+ return new WP_Error( 'unknown_taxonomy', 'Unknown taxonomy', 404 );
+ }
+
+ $args = $this->query_args();
+ $return = $this->get_taxonomy( $term->slug, $taxonomy, $args['context'] );
+ if ( ! $return || is_wp_error( $return ) ) {
+ return $return;
+ }
+
+ /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
+ do_action( 'wpcom_json_api_objects', 'terms' );
+
+ wp_delete_term( $term->term_id, $taxonomy );
+
+ return array(
+ 'slug' => (string) $term->slug,
+ 'success' => true
+ );
+ }
+}
diff --git a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-plugins-modify-endpoint.php b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-plugins-modify-endpoint.php
index 3236862d..fca8173e 100644
--- a/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-plugins-modify-endpoint.php
+++ b/plugins/jetpack/json-endpoints/jetpack/class.jetpack-json-api-plugins-modify-endpoint.php
@@ -148,6 +148,8 @@ class Jetpack_JSON_API_Plugins_Modify_Endpoint extends Jetpack_JSON_API_Plugins_
remove_action( 'upgrader_process_complete', 'wp_version_check' );
remove_action( 'upgrader_process_complete', 'wp_update_themes' );
+ $result = false;
+
foreach ( $this->plugins as $plugin ) {
if ( ! in_array( $plugin, $plugin_updates_needed ) ) {