diff options
Diffstat (limited to 'plugins/jetpack/sal')
-rw-r--r-- | plugins/jetpack/sal/class.json-api-date.php | 35 | ||||
-rw-r--r-- | plugins/jetpack/sal/class.json-api-links.php | 68 | ||||
-rw-r--r-- | plugins/jetpack/sal/class.json-api-post-base.php | 14 | ||||
-rw-r--r-- | plugins/jetpack/sal/class.json-api-site-base.php | 80 | ||||
-rw-r--r-- | plugins/jetpack/sal/class.json-api-site-jetpack-base.php | 24 | ||||
-rw-r--r-- | plugins/jetpack/sal/class.json-api-site-jetpack.php | 24 |
6 files changed, 172 insertions, 73 deletions
diff --git a/plugins/jetpack/sal/class.json-api-date.php b/plugins/jetpack/sal/class.json-api-date.php index d51247c0..c5c0cb38 100644 --- a/plugins/jetpack/sal/class.json-api-date.php +++ b/plugins/jetpack/sal/class.json-api-date.php @@ -52,4 +52,37 @@ class WPCOM_JSON_API_Date { return (string) gmdate( 'Y-m-d\\TH:i:s', $timestamp ) . sprintf( '%s%02d:%02d', $west ? '-' : '+', $hours, $minutes ); } -}
\ No newline at end of file + + /** + * Returns ISO 8601 formatted duration interval: P0DT1H10M0S + * + * @param string $time Duration in minutes or hours. + * + * @return null|string + */ + static function format_duration( $time ) { + $timestamp = strtotime( $time, 0 ); + + // Bail early if we don't recognize a date. + if ( empty( $timestamp ) ) { + return; + } + + $days = floor( $timestamp / 86400 ); + $timestamp = $timestamp % 86400; + + $hours = floor( $timestamp / 3600 ); + $timestamp = $timestamp % 3600; + + $minutes = floor( $timestamp / 60 ); + $timestamp = $timestamp % 60; + + return (string) sprintf( + 'P%dDT%dH%dM%dS', + $days, + $hours, + $minutes, + $timestamp + ); + } +} diff --git a/plugins/jetpack/sal/class.json-api-links.php b/plugins/jetpack/sal/class.json-api-links.php index 39c71067..6746f202 100644 --- a/plugins/jetpack/sal/class.json-api-links.php +++ b/plugins/jetpack/sal/class.json-api-links.php @@ -5,6 +5,9 @@ require_once dirname( __FILE__ ) . '/../class.json-api.php'; class WPCOM_JSON_API_Links { private $api; private static $instance; + private $closest_endpoint_cache_by_version = array(); + private $matches_by_version = array(); + private $cache_result = null; public static function getInstance() { if ( null === self::$instance ) { @@ -38,17 +41,20 @@ class WPCOM_JSON_API_Links { if ( $path ) { $path = '/' . ltrim( $path, '/' ); + // tack the path onto the end of the format string + // have to escape %'s in the path as %% because + // we're about to pass it through sprintf and we don't + // want it to see the % as a placeholder + $format .= str_replace( '%', '%%', $path ); } - $args[] = $path; - // Escape any % in args before using sprintf $escaped_args = array(); foreach ( $args as $arg_key => $arg_value ) { $escaped_args[ $arg_key ] = str_replace( '%', '%%', $arg_value ); } - $relative_path = vsprintf( "$format%s", $escaped_args ); + $relative_path = vsprintf( $format, $escaped_args ); if ( ! wp_startswith( $relative_path, '.' ) ) { // Generic version. Match the requested version as best we can @@ -122,41 +128,49 @@ class WPCOM_JSON_API_Links { * * This method is used in get_link() to construct meta links for API responses. * - * @param $template_path The generic endpoint path, e.g. /sites/%s + * @param $template_path string The generic endpoint path, e.g. /sites/%s * @param $path string The current endpoint path, relative to the version, e.g. /sites/12345 - * @param $method string Request method used to access the endpoint path + * @param $request_method string Request method used to access the endpoint path * @return string The current version, or otherwise the maximum version available */ function get_closest_version_of_endpoint( $template_path, $path, $request_method = 'GET' ) { - static $closest_endpoint_cache; + $closest_endpoint_cache_by_version = & $this->closest_endpoint_cache_by_version; - if ( ! $closest_endpoint_cache ) { - $closest_endpoint_cache = array(); + $closest_endpoint_cache = & $closest_endpoint_cache_by_version[ $this->api->version ]; + if ( !$closest_endpoint_cache ) { + $closest_endpoint_cache_by_version[ $this->api->version ] = array(); + $closest_endpoint_cache = & $closest_endpoint_cache_by_version[ $this->api->version ]; } if ( ! isset( $closest_endpoint_cache[ $template_path ] ) ) { $closest_endpoint_cache[ $template_path ] = array(); } elseif ( isset( $closest_endpoint_cache[ $template_path ][ $request_method ] ) ) { - return $closest_endpoint_cache[ $template_path ][ $request_method ]; + return $closest_endpoint_cache[ $template_path ][ $request_method ]; } $path = untrailingslashit( $path ); // /help is a special case - always use the current request version if ( wp_endswith( $path, '/help' ) ) { - return $closest_endpoint_cache[ $template_path ][ $request_method ] = $this->api->version; + $closest_endpoint_cache[ $template_path ][ $request_method ] = $this->api->version; + return $this->api->version; } - static $matches; - if ( empty( $matches ) ) { - $matches = array(); - } else { - // try to match out of saved matches - foreach( $matches as $match ) { - $regex = $match->regex; - if ( preg_match( "#^$regex\$#", $path ) ) { - return $closest_endpoint_cache[ $template_path ][ $request_method ] = $match->version; - } + $matches_by_version = & $this->matches_by_version; + + // try to match out of saved matches + $matches = isset( $matches_by_version[ $this->api->version ] ) + ? $matches_by_version[ $this->api->version ] + : false; + if ( ! $matches ) { + $matches_by_version[ $this->api->version ] = array(); + $matches = & $matches_by_version[ $this->api->version ]; + } + foreach ( $matches as $match ) { + $regex = $match->regex; + if ( preg_match( "#^$regex\$#", $path ) ) { + $closest_endpoint_cache[ $template_path ][ $request_method ] = $match->version; + return $match->version; } } @@ -189,7 +203,8 @@ class WPCOM_JSON_API_Links { if ( version_compare( $this->api->version, $endpoint['min_version'], '>=') && version_compare( $this->api->version, $endpoint['max_version'], '<=') ) { array_push( $matches, (object) array( 'version' => $this->api->version, 'regex' => $endpoint_path_regex ) ); - return $closest_endpoint_cache[ $template_path ][ $request_method ] = $this->api->version; + $closest_endpoint_cache[ $template_path ][ $request_method ] = $this->api->version; + return $this->api->version; } // If the endpoint doesn't exist at the same version, record the max version we found @@ -202,6 +217,7 @@ class WPCOM_JSON_API_Links { // If the endpoint version is less than the requested endpoint version, return the max version found if ( ! empty( $max_version_found ) ) { array_push( $matches, (object) $max_version_found ); + $closest_endpoint_cache[ $template_path ][ $request_method ] = $max_version_found['version']; return $max_version_found['version']; } @@ -212,16 +228,12 @@ class WPCOM_JSON_API_Links { /** * Get an array of endpoint paths with their associated versions * - * The result is cached for 30 minutes. - * * @return array Array of endpoint paths, min_versions and max_versions, keyed by last segment of path **/ protected function get_endpoint_path_versions() { - static $cache_result; - - if ( ! empty ( $cache_result ) ) { - return $cache_result; + if ( ! empty ( $this->cache_result ) ) { + return $this->cache_result; } /* @@ -246,7 +258,7 @@ class WPCOM_JSON_API_Links { ); } - $cache_result = $endpoint_path_versions; + $this->cache_result = $endpoint_path_versions; return $endpoint_path_versions; } diff --git a/plugins/jetpack/sal/class.json-api-post-base.php b/plugins/jetpack/sal/class.json-api-post-base.php index 37555f8b..96eae901 100644 --- a/plugins/jetpack/sal/class.json-api-post-base.php +++ b/plugins/jetpack/sal/class.json-api-post-base.php @@ -282,12 +282,12 @@ abstract class SAL_Post { $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, + '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'] ) ) { @@ -468,7 +468,7 @@ abstract class SAL_Post { // TODO factor this out if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { $active_blog = get_active_blog_for_user( $user->ID ); - $site_id = $active_blog->get_id(); + $site_id = $active_blog->blog_id; $profile_URL = "http://en.gravatar.com/{$user->user_login}"; } else { $profile_URL = 'http://en.gravatar.com/' . md5( strtolower( trim( $user->user_email ) ) ); diff --git a/plugins/jetpack/sal/class.json-api-site-base.php b/plugins/jetpack/sal/class.json-api-site-base.php index dea8cf91..c4e5aed3 100644 --- a/plugins/jetpack/sal/class.json-api-site-base.php +++ b/plugins/jetpack/sal/class.json-api-site-base.php @@ -41,6 +41,10 @@ abstract class SAL_Site { return (int) wp_count_posts( 'post' )->publish; } + public function get_quota() { + return null; + } + abstract public function has_videopress(); abstract public function upgraded_filetypes_enabled(); @@ -49,6 +53,8 @@ abstract class SAL_Site { abstract public function is_redirect(); + abstract public function is_headstart_fresh(); + abstract public function featured_images_enabled(); abstract public function has_wordads(); @@ -81,6 +87,8 @@ abstract class SAL_Site { abstract public function get_ak_vp_bundle_enabled(); + abstract public function get_podcasting_archive(); + abstract public function get_jetpack_seo_front_page_description(); abstract public function get_jetpack_seo_title_formats(); @@ -97,6 +105,11 @@ abstract class SAL_Site { // wrap a WP_Post object with SAL methods abstract public function wrap_post( $post, $context ); + abstract protected function is_a8c_publication( $post_id ); + + public function is_automated_transfer() { + return false; + } public function get_post_by_id( $post_id, $context ) { $post = get_post( $post_id, OBJECT, $context ); @@ -113,15 +126,16 @@ abstract class SAL_Site { /** * Validate current user can access the post - * + * * @return WP_Error or post */ private function validate_access( $post ) { $context = $post->context; - if ( ! $this->is_post_type_allowed( $post->post_type ) - && - ( ! function_exists( 'is_post_freshly_pressed' ) || ! is_post_freshly_pressed( $post->ID ) ) ) { + if ( + ! $this->is_post_type_allowed( $post->post_type ) + && ! $this->is_a8c_publication( $post->ID ) + ) { return new WP_Error( 'unknown_post', 'Unknown post', 404 ); } @@ -144,8 +158,28 @@ abstract class SAL_Site { return $post; } + public function current_user_can_access_post_type( $post_type, $context ) { + $post_type_object = $this->get_post_type_object( $post_type ); + if ( ! $post_type_object ) { + return false; + } + + switch( $context ) { + case 'edit': + return current_user_can( $post_type_object->cap->edit_posts ); + case 'display': + return $post_type_object->public || current_user_can( $post_type_object->cap->read_private_posts ); + default: + return false; + } + } + + protected function get_post_type_object( $post_type ) { + return get_post_type_object( $post_type ); + } + // copied from class.json-api-endpoints.php - private function is_post_type_allowed( $post_type ) { + public function is_post_type_allowed( $post_type ) { // if the post type is empty, that's fine, WordPress will default to post if ( empty( $post_type ) ) return true; @@ -155,7 +189,7 @@ abstract class SAL_Site { return true; // check for allowed types - if ( in_array( $post_type, $this->_get_whitelisted_post_types() ) ) + if ( in_array( $post_type, $this->get_whitelisted_post_types() ) ) return true; return false; @@ -167,7 +201,7 @@ abstract class SAL_Site { * * @return array Whitelisted post types. */ - private function _get_whitelisted_post_types() { + public function get_whitelisted_post_types() { $allowed_types = array( 'post', 'page', 'revision' ); /** @@ -199,14 +233,14 @@ abstract class SAL_Site { $authorized = ( $post_status_obj->public || - ( is_user_logged_in() && + ( is_user_logged_in() && ( ( $post_status_obj->protected && current_user_can( 'edit_post', $post->ID ) ) || ( $post_status_obj->private && current_user_can( 'read_post', $post->ID ) ) || ( 'trash' === $post->post_status && current_user_can( 'edit_post', $post->ID ) ) || 'auto-draft' === $post->post_status - ) - ) + ) + ) ); if ( ! $authorized ) { @@ -260,7 +294,7 @@ abstract class SAL_Site { $posts = get_posts( array( 'name' => $name, 'numberposts' => 1, - 'post_type' => $this->_get_whitelisted_post_types(), + 'post_type' => $this->get_whitelisted_post_types(), ) ); if ( ! $posts || ! isset( $posts[0]->ID ) || ! $posts[0]->ID ) { @@ -328,9 +362,12 @@ abstract class SAL_Site { 'list_users' => current_user_can( 'list_users' ), 'manage_categories' => current_user_can( 'manage_categories' ), 'manage_options' => current_user_can( 'manage_options' ), + 'activate_wordads' => wpcom_get_blog_owner() === (int) get_current_user_id(), 'promote_users' => current_user_can( 'promote_users' ), 'publish_posts' => current_user_can( 'publish_posts' ), 'upload_files' => current_user_can( 'upload_files' ), + 'delete_users' => current_user_can( 'delete_users' ), + 'remove_users' => current_user_can( 'remove_users' ), 'view_stats' => stats_is_blog_user( $this->blog_id ) ); } @@ -414,12 +451,12 @@ abstract class SAL_Site { } function get_image_thumbnail_width() { - return (int) get_option( 'thumbnail_size_w' ); + return (int) get_option( 'thumbnail_size_w' ); } function get_image_thumbnail_height() { return (int) get_option( 'thumbnail_size_h' ); - } + } function get_image_thumbnail_crop() { return get_option( 'thumbnail_crop' ); @@ -430,7 +467,7 @@ abstract class SAL_Site { } function get_image_medium_height() { - return (int) get_option( 'medium_size_h' ); + return (int) get_option( 'medium_size_h' ); } function get_image_large_width() { @@ -446,9 +483,9 @@ abstract class SAL_Site { } function get_default_post_format() { - return get_option( 'default_post_format' ); + return get_option( 'default_post_format' ); } - + function get_default_category() { return (int) get_option( 'default_category' ); } @@ -480,7 +517,7 @@ abstract class SAL_Site { } function default_ping_status() { - return 'closed' !== get_option( 'default_ping_status' ); + return 'closed' !== get_option( 'default_ping_status' ); } function is_publicize_permanently_disabled() { @@ -488,9 +525,9 @@ abstract class SAL_Site { if ( function_exists( 'is_publicize_permanently_disabled' ) ) { $publicize_permanently_disabled = is_publicize_permanently_disabled( $this->blog_id ); } - return $publicize_permanently_disabled; + return $publicize_permanently_disabled; } - + function get_page_on_front() { return (int) get_option( 'page_on_front' ); } @@ -507,4 +544,9 @@ abstract class SAL_Site { global $wp_version; return $wp_version; } + + function is_domain_only() { + $options = get_option( 'options' ); + return ! empty ( $options['is_domain_only'] ) ? (bool) $options['is_domain_only'] : false; + } } diff --git a/plugins/jetpack/sal/class.json-api-site-jetpack-base.php b/plugins/jetpack/sal/class.json-api-site-jetpack-base.php index ad40198e..5126123f 100644 --- a/plugins/jetpack/sal/class.json-api-site-jetpack-base.php +++ b/plugins/jetpack/sal/class.json-api-site-jetpack-base.php @@ -1,6 +1,5 @@ <?php - require_once dirname( __FILE__ ) . '/class.json-api-site-base.php'; abstract class Abstract_Jetpack_Site extends SAL_Site { @@ -10,9 +9,11 @@ abstract class Abstract_Jetpack_Site extends SAL_Site { abstract protected function get_theme_support( $feature_name ); - abstract protected function get_jetpack_version(); + abstract protected function get_mock_option( $name ); + + abstract public function get_jetpack_version(); - abstract protected function get_updates(); + abstract public function get_updates(); abstract protected function main_network_site(); @@ -22,8 +23,6 @@ abstract class Abstract_Jetpack_Site extends SAL_Site { abstract protected function is_main_network(); - abstract protected function is_multi_site(); - abstract protected function is_version_controlled(); abstract protected function file_system_write_access(); @@ -64,7 +63,7 @@ abstract class Abstract_Jetpack_Site extends SAL_Site { // Sites have to prove that they are not main_network site. // If the sync happends right then we should be able to see that we are not dealing with a network site $options['is_multi_network'] = (bool) $this->is_main_network(); - $options['is_multi_site'] = (bool) $this->is_multi_site(); + $options['is_multi_site'] = (bool) $this->is_multisite(); $file_mod_disabled_reasons = array_keys( array_filter( array( 'automatic_updater_disabled' => (bool) $this->get_constant( 'AUTOMATIC_UPDATER_DISABLED' ), @@ -91,14 +90,6 @@ abstract class Abstract_Jetpack_Site extends SAL_Site { return false; // this may change for VIP Go sites, which sync using Jetpack } - function is_multisite() { - return (bool) is_multisite(); - } - - function is_single_user_site() { - return (bool) Jetpack::is_single_user_site(); - } - function featured_images_enabled() { return $this->current_theme_supports( 'post-thumbnails' ); } @@ -160,4 +151,9 @@ abstract class Abstract_Jetpack_Site extends SAL_Site { return false; } + + // For Jetpack sites this will always return false + protected function is_a8c_publication( $post_id ) { + return false; + } } diff --git a/plugins/jetpack/sal/class.json-api-site-jetpack.php b/plugins/jetpack/sal/class.json-api-site-jetpack.php index 74c97bab..dbf292f1 100644 --- a/plugins/jetpack/sal/class.json-api-site-jetpack.php +++ b/plugins/jetpack/sal/class.json-api-site-jetpack.php @@ -6,6 +6,10 @@ require_once dirname( __FILE__ ) . '/class.json-api-post-jetpack.php'; // this code runs on Jetpack (.org) sites class Jetpack_Site extends Abstract_Jetpack_Site { + protected function get_mock_option( $name ) { + return get_option( 'jetpack_'.$name ); + } + protected function get_constant( $name ) { if ( defined( $name) ) { return constant( $name ); @@ -30,8 +34,12 @@ class Jetpack_Site extends Abstract_Jetpack_Site { return Jetpack::is_multi_network(); } - protected function is_multi_site() { - return is_multisite(); + public function is_multisite() { + return (bool) is_multisite(); + } + + public function is_single_user_site() { + return (bool) Jetpack::is_single_user_site(); } protected function is_version_controlled() { @@ -50,7 +58,7 @@ class Jetpack_Site extends Abstract_Jetpack_Site { return get_theme_support( $feature_name ); } - protected function get_updates() { + public function get_updates() { return (array) Jetpack::get_updates(); } @@ -93,6 +101,10 @@ class Jetpack_Site extends Abstract_Jetpack_Site { return false; } + function is_headstart_fresh() { + return false; + } + function allowed_file_types() { $allowed_file_types = array(); @@ -132,7 +144,7 @@ class Jetpack_Site extends Abstract_Jetpack_Site { return true; } - protected function get_jetpack_version() { + public function get_jetpack_version() { return JETPACK__VERSION; } @@ -150,6 +162,10 @@ class Jetpack_Site extends Abstract_Jetpack_Site { return get_option( 'verification_services_codes', null ); } + function get_podcasting_archive() { + return null; + } + /** * Post functions */ |