Add upstream
This commit is contained in:
88
wp-content/plugins/jetpack/sal/class.json-api-date.php
Normal file
88
wp-content/plugins/jetpack/sal/class.json-api-date.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
class WPCOM_JSON_API_Date {
|
||||
/**
|
||||
* Returns ISO 8601 formatted datetime: 2011-12-08T01:15:36-08:00
|
||||
*
|
||||
* @param $date_gmt (string) GMT datetime string.
|
||||
* @param $date (string) Optional. Used to calculate the offset from GMT.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static function format_date( $date_gmt, $date = null ) {
|
||||
$timestamp_gmt = strtotime( "$date_gmt+0000" );
|
||||
|
||||
if ( null === $date ) {
|
||||
$timestamp = $timestamp_gmt;
|
||||
$hours = $minutes = $west = 0;
|
||||
} else {
|
||||
$date_time = date_create( "$date+0000" );
|
||||
if ( $date_time ) {
|
||||
$timestamp = date_format( $date_time, 'U' );
|
||||
} else {
|
||||
$timestamp = 0;
|
||||
}
|
||||
|
||||
// "0000-00-00 00:00:00" == -62169984000
|
||||
if ( - 62169984000 == $timestamp_gmt ) {
|
||||
// WordPress sets post_date=now, post_date_gmt="0000-00-00 00:00:00" for all drafts
|
||||
// WordPress sets post_modified=now, post_modified_gmt="0000-00-00 00:00:00" for new drafts
|
||||
|
||||
// Try to guess the correct offset from the blog's options.
|
||||
$timezone_string = get_option( 'timezone_string' );
|
||||
|
||||
if ( $timezone_string && $date_time ) {
|
||||
$timezone = timezone_open( $timezone_string );
|
||||
if ( $timezone ) {
|
||||
$offset = $timezone->getOffset( $date_time );
|
||||
}
|
||||
} else {
|
||||
$offset = 3600 * get_option( 'gmt_offset' );
|
||||
}
|
||||
} else {
|
||||
$offset = $timestamp - $timestamp_gmt;
|
||||
}
|
||||
|
||||
$west = $offset < 0;
|
||||
$offset = abs( $offset );
|
||||
$hours = (int) floor( $offset / 3600 );
|
||||
$offset -= $hours * 3600;
|
||||
$minutes = (int) floor( $offset / 60 );
|
||||
}
|
||||
|
||||
return (string) gmdate( 'Y-m-d\\TH:i:s', $timestamp ) . sprintf( '%s%02d:%02d', $west ? '-' : '+', $hours, $minutes );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
}
|
||||
}
|
||||
283
wp-content/plugins/jetpack/sal/class.json-api-links.php
Normal file
283
wp-content/plugins/jetpack/sal/class.json-api-links.php
Normal file
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
|
||||
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 ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
// protect these methods for singleton
|
||||
protected function __construct() {
|
||||
$this->api = WPCOM_JSON_API::init();
|
||||
}
|
||||
private function __clone() { }
|
||||
private function __wakeup() { }
|
||||
|
||||
/**
|
||||
* Generate a URL to an endpoint
|
||||
*
|
||||
* Used to construct meta links in API responses
|
||||
*
|
||||
* @param mixed $args Optional arguments to be appended to URL
|
||||
* @return string Endpoint URL
|
||||
**/
|
||||
function get_link() {
|
||||
$args = func_get_args();
|
||||
$format = array_shift( $args );
|
||||
$base = WPCOM_JSON_API__BASE;
|
||||
|
||||
$path = array_pop( $args );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
// 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, $escaped_args );
|
||||
|
||||
if ( ! wp_startswith( $relative_path, '.' ) ) {
|
||||
// Generic version. Match the requested version as best we can
|
||||
$api_version = $this->get_closest_version_of_endpoint( $format, $relative_path );
|
||||
$base = substr( $base, 0, - 1 ) . $api_version;
|
||||
}
|
||||
|
||||
// escape any % in the relative path before running it through sprintf again
|
||||
$relative_path = str_replace( '%', '%%', $relative_path );
|
||||
// http, WPCOM_JSON_API__BASE, ... , path
|
||||
// %s , %s , $format, %s
|
||||
return esc_url_raw( sprintf( "https://%s$relative_path", $base ) );
|
||||
}
|
||||
|
||||
function get_me_link( $path = '' ) {
|
||||
return $this->get_link( '/me', $path );
|
||||
}
|
||||
|
||||
function get_taxonomy_link( $blog_id, $taxonomy_id, $taxonomy_type, $path = '' ) {
|
||||
switch ( $taxonomy_type ) {
|
||||
case 'category':
|
||||
return $this->get_link( '/sites/%d/categories/slug:%s', $blog_id, $taxonomy_id, $path );
|
||||
|
||||
case 'post_tag':
|
||||
return $this->get_link( '/sites/%d/tags/slug:%s', $blog_id, $taxonomy_id, $path );
|
||||
|
||||
default:
|
||||
return $this->get_link( '/sites/%d/taxonomies/%s/terms/slug:%s', $blog_id, $taxonomy_type, $taxonomy_id, $path );
|
||||
}
|
||||
}
|
||||
|
||||
function get_media_link( $blog_id, $media_id, $path = '' ) {
|
||||
return $this->get_link( '/sites/%d/media/%d', $blog_id, $media_id, $path );
|
||||
}
|
||||
|
||||
function get_site_link( $blog_id, $path = '' ) {
|
||||
return $this->get_link( '/sites/%d', $blog_id, $path );
|
||||
}
|
||||
|
||||
function get_post_link( $blog_id, $post_id, $path = '' ) {
|
||||
return $this->get_link( '/sites/%d/posts/%d', $blog_id, $post_id, $path );
|
||||
}
|
||||
|
||||
function get_comment_link( $blog_id, $comment_id, $path = '' ) {
|
||||
return $this->get_link( '/sites/%d/comments/%d', $blog_id, $comment_id, $path );
|
||||
}
|
||||
|
||||
function get_publicize_connection_link( $blog_id, $publicize_connection_id, $path = '' ) {
|
||||
return $this->get_link( '.1/sites/%d/publicize-connections/%d', $blog_id, $publicize_connection_id, $path );
|
||||
}
|
||||
|
||||
function get_publicize_connections_link( $keyring_token_id, $path = '' ) {
|
||||
return $this->get_link( '.1/me/publicize-connections/?keyring_connection_ID=%d', $keyring_token_id, $path );
|
||||
}
|
||||
|
||||
function get_keyring_connection_link( $keyring_token_id, $path = '' ) {
|
||||
return $this->get_link( '.1/me/keyring-connections/%d', $keyring_token_id, $path );
|
||||
}
|
||||
|
||||
function get_external_service_link( $external_service, $path = '' ) {
|
||||
return $this->get_link( '.1/meta/external-services/%s', $external_service, $path );
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the closest supported version of an endpoint to the current endpoint
|
||||
*
|
||||
* For example, if we were looking at the path /animals/panda:
|
||||
* - if the current endpoint is v1.3 and there is a v1.3 of /animals/%s available, we return 1.3
|
||||
* - if the current endpoint is v1.3 and there is no v1.3 of /animals/%s known, we fall back to the
|
||||
* maximum available version of /animals/%s, e.g. 1.1
|
||||
*
|
||||
* This method is used in get_link() to construct meta links for API responses.
|
||||
*
|
||||
* @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 $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' ) {
|
||||
$closest_endpoint_cache_by_version = & $this->closest_endpoint_cache_by_version;
|
||||
|
||||
$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 ];
|
||||
}
|
||||
|
||||
$path = untrailingslashit( $path );
|
||||
|
||||
// /help is a special case - always use the current request version
|
||||
if ( wp_endswith( $path, '/help' ) ) {
|
||||
$closest_endpoint_cache[ $template_path ][ $request_method ] = $this->api->version;
|
||||
return $this->api->version;
|
||||
}
|
||||
|
||||
$matches_by_version = & $this->matches_by_version;
|
||||
|
||||
// try to match out of saved matches
|
||||
if ( ! isset( $matches_by_version[ $this->api->version ] ) ) {
|
||||
$matches_by_version[ $this->api->version ] = array();
|
||||
}
|
||||
foreach ( $matches_by_version[ $this->api->version ] as $match ) {
|
||||
$regex = $match->regex;
|
||||
if ( preg_match( "#^$regex\$#", $path ) ) {
|
||||
$closest_endpoint_cache[ $template_path ][ $request_method ] = $match->version;
|
||||
return $match->version;
|
||||
}
|
||||
}
|
||||
|
||||
$endpoint_path_versions = $this->get_endpoint_path_versions();
|
||||
$last_path_segment = $this->get_last_segment_of_relative_path( $path );
|
||||
$max_version_found = null;
|
||||
|
||||
foreach ( $endpoint_path_versions as $endpoint_last_path_segment => $endpoints ) {
|
||||
|
||||
// Does the last part of the path match the path key? (e.g. 'posts')
|
||||
// If the last part contains a placeholder (e.g. %s), we want to carry on
|
||||
if ( $last_path_segment != $endpoint_last_path_segment && ! strstr( $endpoint_last_path_segment, '%' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $endpoints as $endpoint ) {
|
||||
// Does the request method match?
|
||||
if ( ! in_array( $request_method, $endpoint['request_methods'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$endpoint_path = untrailingslashit( $endpoint['path'] );
|
||||
$endpoint_path_regex = str_replace( array( '%s', '%d' ), array( '([^/?&]+)', '(\d+)' ), $endpoint_path );
|
||||
|
||||
if ( ! preg_match( "#^$endpoint_path_regex\$#", $path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure the endpoint exists at the same version
|
||||
if ( version_compare( $this->api->version, $endpoint['min_version'], '>=') &&
|
||||
version_compare( $this->api->version, $endpoint['max_version'], '<=') ) {
|
||||
array_push(
|
||||
$matches_by_version[ $this->api->version ],
|
||||
(object) array( 'version' => $this->api->version, 'regex' => $endpoint_path_regex )
|
||||
);
|
||||
$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
|
||||
if ( empty( $max_version_found ) || version_compare( $max_version_found['version'], $endpoint['max_version'], '<' ) ) {
|
||||
$max_version_found = array( 'version' => $endpoint['max_version'], 'regex' => $endpoint_path_regex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the endpoint version is less than the requested endpoint version, return the max version found
|
||||
if ( ! empty( $max_version_found ) ) {
|
||||
array_push(
|
||||
$matches_by_version[ $this->api->version ],
|
||||
(object) $max_version_found
|
||||
);
|
||||
$closest_endpoint_cache[ $template_path ][ $request_method ] = $max_version_found['version'];
|
||||
return $max_version_found['version'];
|
||||
}
|
||||
|
||||
// Otherwise, use the API version of the current request
|
||||
return $this->api->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of endpoint paths with their associated versions
|
||||
*
|
||||
* @return array Array of endpoint paths, min_versions and max_versions, keyed by last segment of path
|
||||
**/
|
||||
protected function get_endpoint_path_versions() {
|
||||
|
||||
if ( ! empty ( $this->cache_result ) ) {
|
||||
return $this->cache_result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a map of endpoints and their min/max versions keyed by the last segment of the path (e.g. 'posts')
|
||||
* This reduces the search space when finding endpoint matches in get_closest_version_of_endpoint()
|
||||
*/
|
||||
$endpoint_path_versions = array();
|
||||
|
||||
foreach ( $this->api->endpoints as $key => $endpoint_objects ) {
|
||||
|
||||
// The key contains a serialized path, min_version and max_version
|
||||
list( $path, $min_version, $max_version ) = unserialize( $key );
|
||||
|
||||
// Grab the last component of the relative path to use as the top-level key
|
||||
$last_path_segment = $this->get_last_segment_of_relative_path( $path );
|
||||
|
||||
$endpoint_path_versions[ $last_path_segment ][] = array(
|
||||
'path' => $path,
|
||||
'min_version' => $min_version,
|
||||
'max_version' => $max_version,
|
||||
'request_methods' => array_keys( $endpoint_objects )
|
||||
);
|
||||
}
|
||||
|
||||
$this->cache_result = $endpoint_path_versions;
|
||||
|
||||
return $endpoint_path_versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the last segment of a relative path
|
||||
*
|
||||
* @param string $path Path
|
||||
* @return string Last path segment
|
||||
*/
|
||||
protected function get_last_segment_of_relative_path( $path) {
|
||||
$path_parts = array_filter( explode( '/', $path ) );
|
||||
|
||||
if ( empty( $path_parts ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return end( $path_parts );
|
||||
}
|
||||
}
|
||||
39
wp-content/plugins/jetpack/sal/class.json-api-metadata.php
Normal file
39
wp-content/plugins/jetpack/sal/class.json-api-metadata.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Utility classes that don't necessarily have a home yet
|
||||
*/
|
||||
|
||||
class WPCOM_JSON_API_Metadata {
|
||||
public static function is_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;
|
||||
}
|
||||
|
||||
public static function is_internal_only( $key ) {
|
||||
|
||||
if ( 0 === strpos( $key, '_jetpack_') )
|
||||
return true;
|
||||
|
||||
if ( 0 === strpos( $key, '_elasticsearch_') )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-platform.php';
|
||||
|
||||
class WPORG_Platform extends SAL_Platform {
|
||||
public function get_site( $blog_id ) {
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-site-jetpack.php';
|
||||
return new Jetpack_Site( $blog_id, $this );
|
||||
}
|
||||
}
|
||||
|
||||
function wpcom_get_sal_platform( $token ) {
|
||||
return new WPORG_Platform( $token );
|
||||
}
|
||||
25
wp-content/plugins/jetpack/sal/class.json-api-platform.php
Normal file
25
wp-content/plugins/jetpack/sal/class.json-api-platform.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-token.php';
|
||||
|
||||
abstract class SAL_Platform {
|
||||
public $token;
|
||||
|
||||
function __construct( $token ) {
|
||||
if ( is_array( $token ) ) {
|
||||
$token = SAL_Token::from_rest_token( $token );
|
||||
} else {
|
||||
$token = SAL_Token::for_anonymous_user();
|
||||
}
|
||||
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
abstract public function get_site( $blog_id );
|
||||
}
|
||||
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-platform-wpcom.php';
|
||||
} else {
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-platform-jetpack.php';
|
||||
}
|
||||
682
wp-content/plugins/jetpack/sal/class.json-api-post-base.php
Normal file
682
wp-content/plugins/jetpack/sal/class.json-api-post-base.php
Normal file
@@ -0,0 +1,682 @@
|
||||
<?php
|
||||
/**
|
||||
* This class wraps a WP_Post and proxies any undefined attributes
|
||||
* and methods to the wrapped class. We need to do this because at present
|
||||
* the WP_Post class is marked as final (in 4.5 this will change, though it's
|
||||
* not clear if there will be a mechanism to retrieve from the DB into the over-
|
||||
* ridden class dynamically).
|
||||
**/
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-metadata.php';
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-date.php';
|
||||
require_once ( ABSPATH . "wp-includes/post.php" );
|
||||
|
||||
abstract class SAL_Post {
|
||||
public $post;
|
||||
public $context;
|
||||
public $site;
|
||||
|
||||
function __construct( $site, $post, $context ) {
|
||||
$this->post = $post;
|
||||
$this->context = $context;
|
||||
$this->site = $site;
|
||||
}
|
||||
|
||||
public function __set( $key, $value ) {
|
||||
$this->post->{ $key } = $value;
|
||||
}
|
||||
|
||||
public function __get( $key ) {
|
||||
if ( $key === 'links' ) {
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-links.php';
|
||||
return WPCOM_JSON_API_Links::getInstance();
|
||||
}
|
||||
return $this->post->{ $key };
|
||||
}
|
||||
|
||||
public function __call( $name, $arguments ) {
|
||||
if ( is_callable( array( $this->post, $name ) ) ) {
|
||||
return call_user_func_array( array( $this->post, $name ), $arguments );
|
||||
} else {
|
||||
trigger_error("Call to undefined method '{$name}'");
|
||||
}
|
||||
}
|
||||
|
||||
public function __isset ( $name ) {
|
||||
return isset( $this->post->{ $name } );
|
||||
}
|
||||
|
||||
abstract public function get_like_count();
|
||||
abstract public function is_liked();
|
||||
abstract public function is_reblogged();
|
||||
abstract public function is_following();
|
||||
abstract public function get_global_id();
|
||||
abstract public function get_geo();
|
||||
|
||||
public function get_menu_order() {
|
||||
return (int) $this->post->menu_order;
|
||||
}
|
||||
|
||||
public function get_guid() {
|
||||
return (string) $this->post->guid;
|
||||
}
|
||||
|
||||
public function get_type() {
|
||||
return (string) $this->post->post_type;
|
||||
}
|
||||
|
||||
public function get_terms() {
|
||||
$taxonomies = get_object_taxonomies( $this->post, 'objects' );
|
||||
$terms = array();
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
if ( ! $taxonomy->public && ! current_user_can( $taxonomy->cap->assign_terms ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$terms[ $taxonomy->name ] = array();
|
||||
|
||||
$taxonomy_terms = wp_get_object_terms( $this->post->ID, $taxonomy->name, array( 'fields' => 'all' ) );
|
||||
foreach ( $taxonomy_terms as $term ) {
|
||||
$formatted_term = $this->format_taxonomy( $term, $taxonomy->name, 'display' );
|
||||
$terms[ $taxonomy->name ][ $term->name ] = $formatted_term;
|
||||
}
|
||||
|
||||
$terms[ $taxonomy->name ] = (object) $terms[ $taxonomy->name ];
|
||||
}
|
||||
|
||||
return (object) $terms;
|
||||
}
|
||||
|
||||
public function get_tags() {
|
||||
$tags = array();
|
||||
$terms = wp_get_post_tags( $this->post->ID );
|
||||
foreach ( $terms as $term ) {
|
||||
if ( !empty( $term->name ) ) {
|
||||
$tags[$term->name] = $this->format_taxonomy( $term, 'post_tag', 'display' );
|
||||
}
|
||||
}
|
||||
return (object) $tags;
|
||||
}
|
||||
|
||||
public function get_categories() {
|
||||
$categories = array();
|
||||
$terms = wp_get_object_terms( $this->post->ID, 'category', array( 'fields' => 'all' ) );
|
||||
foreach ( $terms as $term ) {
|
||||
if ( !empty( $term->name ) ) {
|
||||
$categories[$term->name] = $this->format_taxonomy( $term, 'category', 'display' );
|
||||
}
|
||||
}
|
||||
return (object) $categories;
|
||||
}
|
||||
|
||||
public function get_attachments_and_count() {
|
||||
$attachments = array();
|
||||
$_attachments = new WP_Query( array( 'post_parent' => $this->post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'posts_per_page' => '20' ) );
|
||||
foreach ( $_attachments->posts as $attachment ) {
|
||||
$attachments[$attachment->ID] = $this->get_media_item_v1_1( $attachment->ID );
|
||||
}
|
||||
return array( (object) $attachments, (int) $_attachments->found_posts );
|
||||
}
|
||||
|
||||
public function get_metadata() {
|
||||
$metadata = array();
|
||||
foreach ( (array) has_meta( $this->post->ID ) as $meta ) {
|
||||
// Don't expose protected fields.
|
||||
$meta_key = $meta['meta_key'];
|
||||
|
||||
$show = !( WPCOM_JSON_API_Metadata::is_internal_only( $meta_key ) )
|
||||
&&
|
||||
(
|
||||
WPCOM_JSON_API_Metadata::is_public( $meta_key )
|
||||
||
|
||||
current_user_can( 'edit_post_meta', $this->post->ID , $meta_key )
|
||||
);
|
||||
|
||||
// Only business plan subscribers can view custom meta description
|
||||
if ( Jetpack_SEO_Posts::DESCRIPTION_META_KEY == $meta_key && ! Jetpack_SEO_Utils::is_enabled_jetpack_seo() ) {
|
||||
$show = false;
|
||||
}
|
||||
|
||||
if ( $show ) {
|
||||
$metadata[] = array(
|
||||
'id' => $meta['meta_id'],
|
||||
'key' => $meta['meta_key'],
|
||||
'value' => maybe_unserialize( $meta['meta_value'] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $metadata ) ) {
|
||||
return $metadata;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_meta() {
|
||||
$meta = (object) array(
|
||||
'links' => (object) array(
|
||||
'self' => (string) $this->get_post_link(),
|
||||
'help' => (string) $this->get_post_link( 'help' ),
|
||||
'site' => (string) $this->get_site_link(),
|
||||
'replies' => (string) $this->get_post_link( 'replies/' ),
|
||||
'likes' => (string) $this->get_post_link( 'likes/' ),
|
||||
),
|
||||
);
|
||||
|
||||
$amp_permalink = get_post_meta( $this->post->ID, '_jetpack_amp_permalink', true );
|
||||
|
||||
if ( ! empty( $amp_permalink ) ) {
|
||||
$meta->links->amp = (string) $amp_permalink;
|
||||
}
|
||||
|
||||
// add autosave link if a more recent autosave exists
|
||||
if ( 'edit' === $this->context ) {
|
||||
$autosave = wp_get_post_autosave( $this->post->ID );
|
||||
if ( $autosave && $autosave->post_modified > $this->post->post_modified )
|
||||
$meta->links->autosave = (string) $this->get_post_link() . '/autosave';
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
public function get_current_user_capabilities() {
|
||||
return array(
|
||||
'publish_post' => current_user_can( 'publish_post', $this->post ),
|
||||
'delete_post' => current_user_can( 'delete_post', $this->post ),
|
||||
'edit_post' => current_user_can( 'edit_post', $this->post )
|
||||
);
|
||||
}
|
||||
|
||||
public function get_revisions() {
|
||||
if ( 'edit' !== $this->context ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$revisions = array();
|
||||
$post_revisions = wp_get_post_revisions( $this->post->ID );
|
||||
|
||||
foreach ( $post_revisions as $_post ) {
|
||||
$revisions[] = $_post->ID;
|
||||
}
|
||||
|
||||
return $revisions;
|
||||
}
|
||||
|
||||
public function get_other_urls() {
|
||||
$other_urls = array();
|
||||
|
||||
if ( 'publish' !== $this->post->post_status ) {
|
||||
$other_urls = $this->get_permalink_suggestions( $this->post->post_title );
|
||||
}
|
||||
|
||||
return (object) $other_urls;
|
||||
}
|
||||
|
||||
protected function get_site_link() {
|
||||
return $this->links->get_site_link( $this->site->get_id() );
|
||||
}
|
||||
|
||||
protected function get_post_link( $path = null ) {
|
||||
return $this->links->get_post_link( $this->site->get_id(), $this->post->ID, $path );
|
||||
}
|
||||
|
||||
public function get_publicize_urls() {
|
||||
$publicize_URLs = array();
|
||||
$publicize = get_post_meta( $this->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (array) $publicize_URLs;
|
||||
}
|
||||
|
||||
public function get_page_template() {
|
||||
return (string) get_post_meta( $this->post->ID, '_wp_page_template', true );
|
||||
}
|
||||
|
||||
// note this is overridden in jetpack-shadow
|
||||
public function get_featured_image() {
|
||||
$image_attributes = wp_get_attachment_image_src( get_post_thumbnail_id( $this->post->ID ), 'full' );
|
||||
if ( is_array( $image_attributes ) && isset( $image_attributes[0] ) ) {
|
||||
return (string) $image_attributes[0];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_post_thumbnail() {
|
||||
$thumb = null;
|
||||
|
||||
$thumb_id = get_post_thumbnail_id( $this->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 ) ) {
|
||||
$thumb = (object) $featured_image_object;
|
||||
}
|
||||
}
|
||||
|
||||
return $thumb;
|
||||
}
|
||||
|
||||
public function get_format() {
|
||||
$format = (string) get_post_format( $this->post->ID );
|
||||
if ( !$format ) {
|
||||
$format = 'standard';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
private 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 );
|
||||
}
|
||||
|
||||
public function get_date() {
|
||||
return (string) WPCOM_JSON_API_Date::format_date( $this->post->post_date_gmt, $this->post->post_date );
|
||||
}
|
||||
|
||||
public function get_modified_date() {
|
||||
return (string) WPCOM_JSON_API_Date::format_date( $this->post->post_modified_gmt, $this->post->post_modified );
|
||||
}
|
||||
|
||||
public function get_title() {
|
||||
if ( 'display' === $this->context ) {
|
||||
return (string) get_the_title( $this->post->ID );
|
||||
} else {
|
||||
return (string) htmlspecialchars_decode( $this->post->post_title, ENT_QUOTES );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_url() {
|
||||
if ( 'revision' === $this->post->post_type ) {
|
||||
return (string) esc_url_raw( get_permalink( $this->post->post_parent ) );
|
||||
} else {
|
||||
return (string) esc_url_raw( get_permalink( $this->post->ID ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_shortlink() {
|
||||
return (string) esc_url_raw( wp_get_shortlink( $this->post->ID ) );
|
||||
}
|
||||
|
||||
public function get_content() {
|
||||
if ( 'display' === $this->context ) {
|
||||
// TODO: move this WPCOM-specific hack
|
||||
add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
|
||||
$content = (string) $this->get_the_post_content_for_display();
|
||||
remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
|
||||
return $content;
|
||||
} else {
|
||||
return (string) $this->post->post_content;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_excerpt() {
|
||||
if ( 'display' === $this->context ) {
|
||||
add_filter( 'the_password_form', array( $this, 'the_password_form' ) );
|
||||
ob_start();
|
||||
the_excerpt();
|
||||
$response = (string) ob_get_clean();
|
||||
remove_filter( 'the_password_form', array( $this, 'the_password_form' ) );
|
||||
} else {
|
||||
$response = htmlspecialchars_decode( (string) $this->post->post_excerpt, ENT_QUOTES );
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function get_status() {
|
||||
return (string) get_post_status( $this->post->ID );
|
||||
}
|
||||
|
||||
public function is_sticky() {
|
||||
return (bool) is_sticky( $this->post->ID );
|
||||
}
|
||||
|
||||
public function get_slug() {
|
||||
return (string) $this->post->post_name;
|
||||
}
|
||||
|
||||
public function get_password() {
|
||||
$password = (string) $this->post->post_password;
|
||||
if ( 'edit' === $this->context ) {
|
||||
$password = htmlspecialchars_decode( (string) $password, ENT_QUOTES );
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
public function get_parent() {
|
||||
if ( $this->post->post_parent ) {
|
||||
$parent = get_post( $this->post->post_parent );
|
||||
if ( 'display' === $this->context ) {
|
||||
$parent_title = (string) get_the_title( $parent->ID );
|
||||
} else {
|
||||
$parent_title = (string) htmlspecialchars_decode( $this->post->post_title, ENT_QUOTES );
|
||||
}
|
||||
return (object) array(
|
||||
'ID' => (int) $parent->ID,
|
||||
'type' => (string) $parent->post_type,
|
||||
'link' => (string) $this->links->get_post_link( $this->site->get_id(), $parent->ID ),
|
||||
'title' => $parent_title,
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function the_password_form() {
|
||||
return __( 'This post is password protected.', 'jetpack' );
|
||||
}
|
||||
|
||||
public function get_discussion() {
|
||||
return array(
|
||||
'comments_open' => (bool) comments_open( $this->post->ID ),
|
||||
'comment_status' => (string) $this->post->comment_status,
|
||||
'pings_open' => (bool) pings_open( $this->post->ID ),
|
||||
'ping_status' => (string) $this->post->ping_status,
|
||||
'comment_count' => (int) $this->post->comment_count,
|
||||
);
|
||||
}
|
||||
|
||||
public function is_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 = get_post_meta( $this->post->ID, 'switch_like_status', true );
|
||||
|
||||
return $post_likes_switched || ( $sitewide_likes_enabled && $post_likes_switched !== '0' );
|
||||
}
|
||||
|
||||
public function is_sharing_enabled() {
|
||||
$show = true;
|
||||
/** This filter is documented in modules/sharedaddy/sharing-service.php */
|
||||
$show = apply_filters( 'sharing_show', $show, $this->post );
|
||||
|
||||
$switched_status = get_post_meta( $this->post->ID, 'sharing_disabled', false );
|
||||
|
||||
if ( !empty( $switched_status ) )
|
||||
$show = false;
|
||||
|
||||
return (bool) $show;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
public function get_author() {
|
||||
if ( 0 == $this->post->post_author )
|
||||
return null;
|
||||
|
||||
$show_email = $this->context === 'edit' && current_user_can( 'edit_post', $this->post );
|
||||
|
||||
$user = get_user_by( 'id', $this->post->post_author );
|
||||
|
||||
if ( ! $user || is_wp_error( $user ) ) {
|
||||
trigger_error( 'Unknown user', E_USER_WARNING );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO factor this out
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
$active_blog = get_active_blog_for_user( $user->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 ) ) );
|
||||
$site_id = -1;
|
||||
}
|
||||
|
||||
$author = array(
|
||||
'ID' => (int) $user->ID,
|
||||
'login' => (string) $user->user_login,
|
||||
'email' => $show_email ? (string) $user->user_email : false, // (string|bool)
|
||||
'name' => (string) $user->display_name,
|
||||
'first_name' => (string) $user->first_name,
|
||||
'last_name' => (string) $user->last_name,
|
||||
'nice_name' => (string) $user->user_nicename,
|
||||
'URL' => (string) esc_url_raw( $user->user_url ),
|
||||
'avatar_URL' => (string) esc_url_raw( $this->get_avatar_url( $user->user_email ) ),
|
||||
'profile_URL' => (string) esc_url_raw( $profile_URL )
|
||||
);
|
||||
|
||||
if ($site_id > -1) {
|
||||
$author['site_ID'] = (int) $site_id;
|
||||
}
|
||||
|
||||
return (object) $author;
|
||||
}
|
||||
|
||||
protected function get_avatar_url( $email, $avatar_size = 96 ) {
|
||||
$avatar_url = wpcom_get_avatar_url( $email, $avatar_size, '', true );
|
||||
if ( ! $avatar_url || is_wp_error( $avatar_url ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return esc_url_raw( htmlspecialchars_decode( $avatar_url[0] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extra post permalink suggestions
|
||||
* @return array array of permalink suggestions: 'permalink_URL', 'suggested_slug'
|
||||
*/
|
||||
public function get_permalink_suggestions( $title ) {
|
||||
$suggestions = array();
|
||||
list( $suggestions['permalink_URL'], $suggestions['suggested_slug'] ) = get_sample_permalink( $this->post->ID, $title );
|
||||
return $suggestions;
|
||||
}
|
||||
|
||||
private function format_taxonomy( $taxonomy, $taxonomy_type, $context ) {
|
||||
// Permissions
|
||||
switch ( $context ) {
|
||||
case 'edit' :
|
||||
$tax = get_taxonomy( $taxonomy_type );
|
||||
if ( !current_user_can( $tax->cap->edit_terms ) )
|
||||
return new WP_Error( 'unauthorized', 'User cannot edit taxonomy', 403 );
|
||||
break;
|
||||
case 'display' :
|
||||
if ( -1 == get_option( 'blog_public' ) && ! current_user_can( 'read' ) ) {
|
||||
return new WP_Error( 'unauthorized', 'User cannot view taxonomy', 403 );
|
||||
}
|
||||
break;
|
||||
default :
|
||||
return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
|
||||
}
|
||||
|
||||
$response = array();
|
||||
$response['ID'] = (int) $taxonomy->term_id;
|
||||
$response['name'] = (string) $taxonomy->name;
|
||||
$response['slug'] = (string) $taxonomy->slug;
|
||||
$response['description'] = (string) $taxonomy->description;
|
||||
$response['post_count'] = (int) $taxonomy->count;
|
||||
|
||||
if ( is_taxonomy_hierarchical( $taxonomy_type ) ) {
|
||||
$response['parent'] = (int) $taxonomy->parent;
|
||||
}
|
||||
|
||||
$response['meta'] = (object) array(
|
||||
'links' => (object) array(
|
||||
'self' => (string) $this->links->get_taxonomy_link( $this->site->get_id(), $taxonomy->slug, $taxonomy_type ),
|
||||
'help' => (string) $this->links->get_taxonomy_link( $this->site->get_id(), $taxonomy->slug, $taxonomy_type, 'help' ),
|
||||
'site' => (string) $this->links->get_site_link( $this->site->get_id() ),
|
||||
),
|
||||
);
|
||||
|
||||
return (object) $response;
|
||||
}
|
||||
|
||||
// TODO: factor this out into site
|
||||
private function get_media_item_v1_1( $media_id ) {
|
||||
$media_item = get_post( $media_id );
|
||||
|
||||
if ( ! $media_item || is_wp_error( $media_item ) )
|
||||
return new WP_Error( 'unknown_media', 'Unknown Media', 404 );
|
||||
|
||||
$file = basename( wp_get_attachment_url( $media_item->ID ) );
|
||||
$file_info = pathinfo( $file );
|
||||
$ext = $file_info['extension'];
|
||||
|
||||
$response = array(
|
||||
'ID' => $media_item->ID,
|
||||
'URL' => wp_get_attachment_url( $media_item->ID ),
|
||||
'guid' => $media_item->guid,
|
||||
'date' => (string) WPCOM_JSON_API_Date::format_date( $media_item->post_date_gmt, $media_item->post_date ),
|
||||
'post_ID' => $media_item->post_parent,
|
||||
'author_ID' => (int) $media_item->post_author,
|
||||
'file' => $file,
|
||||
'mime_type' => $media_item->post_mime_type,
|
||||
'extension' => $ext,
|
||||
'title' => $media_item->post_title,
|
||||
'caption' => $media_item->post_excerpt,
|
||||
'description' => $media_item->post_content,
|
||||
'alt' => get_post_meta( $media_item->ID, '_wp_attachment_image_alt', true ),
|
||||
'thumbnails' => array()
|
||||
);
|
||||
|
||||
if ( in_array( $ext, array( 'jpg', 'jpeg', 'png', 'gif' ) ) ) {
|
||||
$metadata = wp_get_attachment_metadata( $media_item->ID );
|
||||
if ( isset( $metadata['height'], $metadata['width'] ) ) {
|
||||
$response['height'] = $metadata['height'];
|
||||
$response['width'] = $metadata['width'];
|
||||
}
|
||||
|
||||
if ( isset( $metadata['sizes'] ) ) {
|
||||
/**
|
||||
* Filter the thumbnail sizes available for each attachment ID.
|
||||
*
|
||||
* @module json-api
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param array $metadata['sizes'] Array of thumbnail sizes available for a given attachment ID.
|
||||
* @param string $media_id Attachment ID.
|
||||
*/
|
||||
$sizes = apply_filters( 'rest_api_thumbnail_sizes', $metadata['sizes'], $media_id );
|
||||
if ( is_array( $sizes ) ) {
|
||||
foreach ( $sizes as $size => $size_details ) {
|
||||
$response['thumbnails'][ $size ] = dirname( $response['URL'] ) . '/' . $size_details['file'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $metadata['image_meta'] ) ) {
|
||||
$response['exif'] = $metadata['image_meta'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( $ext, array( 'mp3', 'm4a', 'wav', 'ogg' ) ) ) {
|
||||
$metadata = wp_get_attachment_metadata( $media_item->ID );
|
||||
$response['length'] = $metadata['length'];
|
||||
$response['exif'] = $metadata;
|
||||
}
|
||||
|
||||
if ( in_array( $ext, array( 'ogv', 'mp4', 'mov', 'wmv', 'avi', 'mpg', '3gp', '3g2', 'm4v' ) ) ) {
|
||||
$metadata = wp_get_attachment_metadata( $media_item->ID );
|
||||
if ( isset( $metadata['height'], $metadata['width'] ) ) {
|
||||
$response['height'] = $metadata['height'];
|
||||
$response['width'] = $metadata['width'];
|
||||
}
|
||||
|
||||
if ( isset( $metadata['length'] ) ) {
|
||||
$response['length'] = $metadata['length'];
|
||||
}
|
||||
|
||||
// add VideoPress info
|
||||
if ( function_exists( 'video_get_info_by_blogpostid' ) ) {
|
||||
$info = video_get_info_by_blogpostid( $this->site->get_id(), $media_id );
|
||||
|
||||
// Thumbnails
|
||||
if ( function_exists( 'video_format_done' ) && function_exists( 'video_image_url_by_guid' ) ) {
|
||||
$response['thumbnails'] = array( 'fmt_hd' => '', 'fmt_dvd' => '', 'fmt_std' => '' );
|
||||
foreach ( $response['thumbnails'] as $size => $thumbnail_url ) {
|
||||
if ( video_format_done( $info, $size ) ) {
|
||||
$response['thumbnails'][ $size ] = video_image_url_by_guid( $info->guid, $size );
|
||||
} else {
|
||||
unset( $response['thumbnails'][ $size ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response['videopress_guid'] = $info->guid;
|
||||
$response['videopress_processing_done'] = true;
|
||||
if ( '0000-00-00 00:00:00' == $info->finish_date_gmt ) {
|
||||
$response['videopress_processing_done'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response['thumbnails'] = (object) $response['thumbnails'];
|
||||
|
||||
$response['meta'] = (object) array(
|
||||
'links' => (object) array(
|
||||
'self' => (string) $this->links->get_media_link( $this->site->get_id(), $media_id ),
|
||||
'help' => (string) $this->links->get_media_link( $this->site->get_id(), $media_id, 'help' ),
|
||||
'site' => (string) $this->links->get_site_link( $this->site->get_id() ),
|
||||
),
|
||||
);
|
||||
|
||||
// add VideoPress link to the meta
|
||||
if ( in_array( $ext, array( 'ogv', 'mp4', 'mov', 'wmv', 'avi', 'mpg', '3gp', '3g2', 'm4v' ) ) ) {
|
||||
if ( function_exists( 'video_get_info_by_blogpostid' ) ) {
|
||||
$response['meta']->links->videopress = (string) $this->links->get_link( '/videos/%s', $response['videopress_guid'], '' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $media_item->post_parent > 0 ) {
|
||||
$response['meta']->links->parent = (string) $this->links->get_post_link( $this->site->get_id(), $media_item->post_parent );
|
||||
}
|
||||
|
||||
return (object) $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
class Jetpack_Post extends SAL_Post {
|
||||
public function get_like_count() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function is_liked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_reblogged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_following() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_global_id() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public function get_geo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function get_avatar_url( $email, $avatar_size = 96 ) {
|
||||
$avatar_url = get_avatar_url( $email, array(
|
||||
'size' => $avatar_size,
|
||||
) );
|
||||
|
||||
if ( ! $avatar_url || is_wp_error( $avatar_url ) ) {
|
||||
return '';
|
||||
}
|
||||
return $avatar_url;
|
||||
}
|
||||
}
|
||||
647
wp-content/plugins/jetpack/sal/class.json-api-site-base.php
Normal file
647
wp-content/plugins/jetpack/sal/class.json-api-site-base.php
Normal file
@@ -0,0 +1,647 @@
|
||||
<?php
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-date.php';
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-post-base.php';
|
||||
|
||||
/**
|
||||
* Base class for the Site Abstraction Layer (SAL)
|
||||
* Note that this is the site "as seen by user $user_id with token $token", which
|
||||
* is why we pass the token to the platform; these site instances are value objects
|
||||
* to be used in the context of a single request for a single user.
|
||||
* Also note that at present this class _assumes_ you've "switched to"
|
||||
* the site in question, and functions like `get_bloginfo( 'name' )` will
|
||||
* therefore return the correct value
|
||||
**/
|
||||
abstract class SAL_Site {
|
||||
public $blog_id;
|
||||
public $platform;
|
||||
|
||||
public function __construct( $blog_id, $platform ) {
|
||||
$this->blog_id = $blog_id;
|
||||
$this->platform = $platform;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->blog_id;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return (string) htmlspecialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
|
||||
}
|
||||
|
||||
public function get_description() {
|
||||
return (string) htmlspecialchars_decode( get_bloginfo( 'description' ), ENT_QUOTES );
|
||||
}
|
||||
|
||||
public function get_url() {
|
||||
return (string) home_url();
|
||||
}
|
||||
|
||||
public function get_post_count() {
|
||||
return (int) wp_count_posts( 'post' )->publish;
|
||||
}
|
||||
|
||||
public function get_quota() {
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract public function has_videopress();
|
||||
|
||||
abstract public function upgraded_filetypes_enabled();
|
||||
|
||||
abstract public function is_mapped_domain();
|
||||
|
||||
abstract public function is_redirect();
|
||||
|
||||
abstract public function is_headstart_fresh();
|
||||
|
||||
abstract public function featured_images_enabled();
|
||||
|
||||
abstract public function has_wordads();
|
||||
|
||||
abstract public function get_frame_nonce();
|
||||
|
||||
abstract public function get_jetpack_frame_nonce();
|
||||
|
||||
abstract public function allowed_file_types();
|
||||
|
||||
abstract public function get_post_formats();
|
||||
|
||||
abstract public function is_private();
|
||||
|
||||
abstract public function is_following();
|
||||
|
||||
abstract public function get_subscribers_count();
|
||||
|
||||
abstract public function get_locale();
|
||||
|
||||
abstract public function is_jetpack();
|
||||
|
||||
abstract public function get_jetpack_modules();
|
||||
|
||||
abstract public function is_module_active( $module );
|
||||
|
||||
abstract public function is_vip();
|
||||
|
||||
abstract public function is_multisite();
|
||||
|
||||
abstract public function is_single_user_site();
|
||||
|
||||
abstract public function get_plan();
|
||||
|
||||
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();
|
||||
|
||||
abstract public function get_verification_services_codes();
|
||||
|
||||
abstract public function before_render();
|
||||
|
||||
abstract public function after_render( &$response );
|
||||
|
||||
// TODO - factor this out? Seems an odd thing to have on a site
|
||||
abstract public function after_render_options( &$options );
|
||||
|
||||
// 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() {
|
||||
/**
|
||||
* Filter if a site is an automated-transfer site.
|
||||
*
|
||||
* @module json-api
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param bool is_automated_transfer( $this->blog_id )
|
||||
* @param int $blog_id Blog identifier.
|
||||
*/
|
||||
return apply_filters(
|
||||
'jetpack_site_automated_transfer',
|
||||
false,
|
||||
$this->blog_id
|
||||
);
|
||||
}
|
||||
|
||||
public function is_wpcom_atomic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function is_wpcom_store() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function woocommerce_is_active() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_post_by_id( $post_id, $context ) {
|
||||
// Remove the skyword tracking shortcode for posts returned via the API.
|
||||
remove_shortcode( 'skyword-tracking' );
|
||||
add_shortcode( 'skyword-tracking', '__return_empty_string' );
|
||||
|
||||
$post = get_post( $post_id, OBJECT, $context );
|
||||
|
||||
if ( ! $post ) {
|
||||
return new WP_Error( 'unknown_post', 'Unknown post', 404 );
|
||||
}
|
||||
|
||||
$wrapped_post = $this->wrap_post( $post, $context );
|
||||
|
||||
// validate access
|
||||
return $this->validate_access( $wrapped_post );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
&& ! $this->is_a8c_publication( $post->ID )
|
||||
) {
|
||||
return new WP_Error( 'unknown_post', 'Unknown post', 404 );
|
||||
}
|
||||
|
||||
switch ( $context ) {
|
||||
case 'edit' :
|
||||
if ( ! current_user_can( 'edit_post', $post->ID ) ) {
|
||||
return new WP_Error( 'unauthorized', 'User cannot edit post', 403 );
|
||||
}
|
||||
break;
|
||||
case 'display' :
|
||||
$can_view = $this->user_can_view_post( $post );
|
||||
if ( is_wp_error( $can_view ) ) {
|
||||
return $can_view;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
return new WP_Error( 'invalid_context', 'Invalid API CONTEXT', 400 );
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// allow special 'any' type
|
||||
if ( 'any' == $post_type ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for allowed types
|
||||
if ( in_array( $post_type, $this->get_whitelisted_post_types() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $post_type_object = get_post_type_object( $post_type ) ) {
|
||||
if ( ! empty( $post_type_object->show_in_rest ) ) {
|
||||
return $post_type_object->show_in_rest;
|
||||
}
|
||||
if ( ! empty( $post_type_object->publicly_queryable ) ) {
|
||||
return $post_type_object->publicly_queryable;
|
||||
}
|
||||
}
|
||||
|
||||
return ! empty( $post_type_object->public );
|
||||
}
|
||||
|
||||
// copied from class.json-api-endpoints.php
|
||||
/**
|
||||
* Gets the whitelisted post types that JP should allow access to.
|
||||
*
|
||||
* @return array Whitelisted post types.
|
||||
*/
|
||||
public function get_whitelisted_post_types() {
|
||||
$allowed_types = array( 'post', 'page', 'revision' );
|
||||
|
||||
/**
|
||||
* Filter the post types Jetpack has access to, and can synchronize with WordPress.com.
|
||||
*
|
||||
* @module json-api
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param array $allowed_types Array of whitelisted post types. Default to `array( 'post', 'page', 'revision' )`.
|
||||
*/
|
||||
$allowed_types = apply_filters( 'rest_api_allowed_post_types', $allowed_types );
|
||||
|
||||
return array_unique( $allowed_types );
|
||||
}
|
||||
|
||||
// copied and modified a little from class.json-api-endpoints.php
|
||||
private function user_can_view_post( $post ) {
|
||||
if ( !$post || is_wp_error( $post ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'inherit' === $post->post_status ) {
|
||||
$parent_post = get_post( $post->post_parent );
|
||||
$post_status_obj = get_post_status_object( $parent_post->post_status );
|
||||
} else {
|
||||
$post_status_obj = get_post_status_object( $post->post_status );
|
||||
}
|
||||
|
||||
$authorized = (
|
||||
$post_status_obj->public ||
|
||||
( 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 ) {
|
||||
return new WP_Error( 'unauthorized', 'User cannot view post', 403 );
|
||||
}
|
||||
|
||||
if (
|
||||
-1 == get_option( 'blog_public' ) &&
|
||||
/**
|
||||
* Filter access to a specific post.
|
||||
*
|
||||
* @module json-api
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param bool current_user_can( 'read_post', $post->ID ) Can the current user access the post.
|
||||
* @param WP_Post $post Post data.
|
||||
*/
|
||||
! apply_filters(
|
||||
'wpcom_json_api_user_can_view_post',
|
||||
current_user_can( 'read_post', $post->ID ),
|
||||
$post
|
||||
)
|
||||
) {
|
||||
return new WP_Error( 'unauthorized', 'User cannot view post', array( 'status_code' => 403, 'error' => 'private_blog' ) );
|
||||
}
|
||||
|
||||
if ( strlen( $post->post_password ) && !current_user_can( 'edit_post', $post->ID ) ) {
|
||||
return new WP_Error( 'unauthorized', 'User cannot view password protected post', array( 'status_code' => 403, 'error' => 'password_protected' ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public 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,
|
||||
'numberposts' => 1,
|
||||
'post_type' => $this->get_whitelisted_post_types(),
|
||||
) );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
return $page->ID;
|
||||
}
|
||||
|
||||
return (int) $posts[0]->ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post by name
|
||||
*
|
||||
* Attempts to match name on post title and page path
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $context (display or edit)
|
||||
*
|
||||
* @return object Post object on success, WP_Error object on failure
|
||||
**/
|
||||
public function get_post_by_name( $name, $context ) {
|
||||
$post_id = $this->get_post_id_by_name( $name );
|
||||
if ( is_wp_error( $post_id ) ) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
return $this->get_post_by_id( $post_id, $context );
|
||||
}
|
||||
|
||||
function user_can_manage() {
|
||||
current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
function get_xmlrpc_url() {
|
||||
$xmlrpc_scheme = apply_filters( 'wpcom_json_api_xmlrpc_scheme', parse_url( get_option( 'home' ), PHP_URL_SCHEME ) );
|
||||
return site_url( 'xmlrpc.php', $xmlrpc_scheme );
|
||||
}
|
||||
|
||||
function get_registered_date() {
|
||||
if ( function_exists( 'get_blog_details' ) ) {
|
||||
$blog_details = get_blog_details();
|
||||
if ( ! empty( $blog_details->registered ) ) {
|
||||
return WPCOM_JSON_API_Date::format_date( $blog_details->registered );
|
||||
}
|
||||
}
|
||||
|
||||
return '0000-00-00T00:00:00+00:00';
|
||||
}
|
||||
|
||||
function get_capabilities() {
|
||||
return array(
|
||||
'edit_pages' => current_user_can( 'edit_pages' ),
|
||||
'edit_posts' => current_user_can( 'edit_posts' ),
|
||||
'edit_others_posts' => current_user_can( 'edit_others_posts' ),
|
||||
'edit_others_pages' => current_user_can( 'edit_others_pages' ),
|
||||
'delete_posts' => current_user_can( 'delete_posts' ),
|
||||
'delete_others_posts' => current_user_can( 'delete_others_posts' ),
|
||||
'edit_theme_options' => current_user_can( 'edit_theme_options' ),
|
||||
'edit_users' => current_user_can( 'edit_users' ),
|
||||
'list_users' => current_user_can( 'list_users' ),
|
||||
'manage_categories' => current_user_can( 'manage_categories' ),
|
||||
'manage_options' => current_user_can( 'manage_options' ),
|
||||
'moderate_comments' => current_user_can( 'moderate_comments' ),
|
||||
'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 )
|
||||
);
|
||||
}
|
||||
|
||||
function is_visible() {
|
||||
if ( is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
$visible = (array) get_user_meta( $current_user->ID, 'blog_visibility', true );
|
||||
|
||||
$is_visible = true;
|
||||
if ( isset( $visible[ $this->blog_id ] ) ) {
|
||||
$is_visible = (bool) $visible[ $this->blog_id ];
|
||||
}
|
||||
|
||||
// null and true are visible
|
||||
return $is_visible;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function get_logo() {
|
||||
|
||||
// Set an empty response array.
|
||||
$logo_setting = array(
|
||||
'id' => (int) 0,
|
||||
'sizes' => array(),
|
||||
'url' => '',
|
||||
);
|
||||
|
||||
// Get current site logo values.
|
||||
$logo = get_option( 'site_logo' );
|
||||
|
||||
// Update the response array if there's a site logo currenty active.
|
||||
if ( $logo && 0 != $logo['id'] ) {
|
||||
$logo_setting['id'] = $logo['id'];
|
||||
$logo_setting['url'] = $logo['url'];
|
||||
|
||||
foreach ( $logo['sizes'] as $size => $properties ) {
|
||||
$logo_setting['sizes'][ $size ] = $properties;
|
||||
}
|
||||
}
|
||||
|
||||
return $logo_setting;
|
||||
}
|
||||
|
||||
function get_timezone() {
|
||||
return (string) get_option( 'timezone_string' );
|
||||
}
|
||||
|
||||
function get_gmt_offset() {
|
||||
return (float) get_option( 'gmt_offset' );
|
||||
}
|
||||
|
||||
function get_login_url() {
|
||||
return wp_login_url();
|
||||
}
|
||||
|
||||
function get_admin_url() {
|
||||
return get_admin_url();
|
||||
}
|
||||
|
||||
function get_unmapped_url() {
|
||||
return get_site_url( get_current_blog_id() );
|
||||
}
|
||||
|
||||
function get_theme_slug() {
|
||||
return get_option( 'stylesheet' );
|
||||
}
|
||||
|
||||
function get_header_image() {
|
||||
return get_theme_mod( 'header_image_data' );
|
||||
}
|
||||
|
||||
function get_background_color() {
|
||||
return get_theme_mod( 'background_color' );
|
||||
}
|
||||
|
||||
function get_image_default_link_type() {
|
||||
return get_option( 'image_default_link_type' );
|
||||
}
|
||||
|
||||
function get_image_thumbnail_width() {
|
||||
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' );
|
||||
}
|
||||
|
||||
function get_image_medium_width() {
|
||||
return (int) get_option( 'medium_size_w' );
|
||||
}
|
||||
|
||||
function get_image_medium_height() {
|
||||
return (int) get_option( 'medium_size_h' );
|
||||
}
|
||||
|
||||
function get_image_large_width() {
|
||||
return (int) get_option( 'large_size_w' );
|
||||
}
|
||||
|
||||
function get_image_large_height() {
|
||||
return (int) get_option( 'large_size_h' );
|
||||
}
|
||||
|
||||
function get_permalink_structure() {
|
||||
return get_option( 'permalink_structure' );
|
||||
}
|
||||
|
||||
function get_default_post_format() {
|
||||
return get_option( 'default_post_format' );
|
||||
}
|
||||
|
||||
function get_default_category() {
|
||||
return (int) get_option( 'default_category' );
|
||||
}
|
||||
|
||||
function get_show_on_front() {
|
||||
return get_option( 'show_on_front' );
|
||||
}
|
||||
|
||||
function is_custom_front_page() {
|
||||
return ( 'page' === $this->get_show_on_front() );
|
||||
}
|
||||
|
||||
function get_default_likes_enabled() {
|
||||
return (bool) apply_filters( 'wpl_is_enabled_sitewide', ! get_option( 'disabled_likes' ) );
|
||||
}
|
||||
|
||||
function get_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'] );
|
||||
}
|
||||
return (bool) $default_sharing_status;
|
||||
}
|
||||
|
||||
function get_default_comment_status() {
|
||||
return 'closed' !== get_option( 'default_comment_status' );
|
||||
}
|
||||
|
||||
function default_ping_status() {
|
||||
return 'closed' !== get_option( 'default_ping_status' );
|
||||
}
|
||||
|
||||
function is_publicize_permanently_disabled() {
|
||||
$publicize_permanently_disabled = false;
|
||||
if ( function_exists( 'is_publicize_permanently_disabled' ) ) {
|
||||
$publicize_permanently_disabled = is_publicize_permanently_disabled( $this->blog_id );
|
||||
}
|
||||
return $publicize_permanently_disabled;
|
||||
}
|
||||
|
||||
function get_page_on_front() {
|
||||
return (int) get_option( 'page_on_front' );
|
||||
}
|
||||
|
||||
function get_page_for_posts() {
|
||||
return (int) get_option( 'page_for_posts' );
|
||||
}
|
||||
|
||||
function is_headstart() {
|
||||
return get_option( 'headstart' );
|
||||
}
|
||||
|
||||
function get_wordpress_version() {
|
||||
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;
|
||||
}
|
||||
|
||||
function get_blog_public() {
|
||||
return (int) get_option( 'blog_public' );
|
||||
}
|
||||
|
||||
function has_pending_automated_transfer() {
|
||||
/**
|
||||
* Filter if a site is in pending automated transfer state.
|
||||
*
|
||||
* @module json-api
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param bool has_site_pending_automated_transfer( $this->blog_id )
|
||||
* @param int $blog_id Blog identifier.
|
||||
*/
|
||||
return apply_filters(
|
||||
'jetpack_site_pending_automated_transfer',
|
||||
false,
|
||||
$this->blog_id
|
||||
);
|
||||
}
|
||||
|
||||
function signup_is_store() {
|
||||
return $this->get_design_type() === 'store';
|
||||
}
|
||||
|
||||
function get_roles() {
|
||||
return new WP_Roles();
|
||||
}
|
||||
|
||||
function get_design_type() {
|
||||
$options = get_option( 'options' );
|
||||
return empty( $options[ 'designType'] ) ? null : $options[ 'designType' ];
|
||||
}
|
||||
|
||||
function get_site_goals() {
|
||||
$options = get_option( 'options' );
|
||||
return empty( $options[ 'siteGoals'] ) ? null : $options[ 'siteGoals' ];
|
||||
}
|
||||
|
||||
function get_launch_status() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_site_segment() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-site-base.php';
|
||||
|
||||
abstract class Abstract_Jetpack_Site extends SAL_Site {
|
||||
abstract protected function get_constant( $name );
|
||||
|
||||
abstract protected function current_theme_supports( $feature_name );
|
||||
|
||||
abstract protected function get_theme_support( $feature_name );
|
||||
|
||||
abstract protected function get_mock_option( $name );
|
||||
|
||||
abstract public function get_jetpack_version();
|
||||
|
||||
abstract public function get_updates();
|
||||
|
||||
abstract protected function main_network_site();
|
||||
|
||||
abstract protected function wp_version();
|
||||
|
||||
abstract protected function max_upload_size();
|
||||
|
||||
abstract protected function is_main_network();
|
||||
|
||||
abstract protected function is_version_controlled();
|
||||
|
||||
abstract protected function file_system_write_access();
|
||||
|
||||
function before_render() {
|
||||
}
|
||||
|
||||
protected function wp_memory_limit() {
|
||||
return $this->get_constant( 'WP_MEMORY_LIMIT' );
|
||||
}
|
||||
|
||||
protected function wp_max_memory_limit() {
|
||||
return $this->get_constant( 'WP_MAX_MEMORY_LIMIT' );
|
||||
}
|
||||
|
||||
|
||||
function after_render( &$response ) {
|
||||
// Add the updates only make them visible if the user has manage options permission and the site is the main site of the network
|
||||
if ( current_user_can( 'manage_options' ) && $this->is_main_site( $response ) ) {
|
||||
$jetpack_update = $this->get_updates();
|
||||
if ( ! empty( $jetpack_update ) ) {
|
||||
// In previous version of Jetpack 3.4, 3.5, 3.6 we synced the wp_version into to jetpack_updates
|
||||
unset( $jetpack_update['wp_version'] );
|
||||
// In previous version of Jetpack 3.4, 3.5, 3.6 we synced the site_is_version_controlled into to jetpack_updates
|
||||
unset( $jetpack_update['site_is_version_controlled'] );
|
||||
|
||||
$response['updates'] = $jetpack_update;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function after_render_options( &$options ) {
|
||||
|
||||
$options['jetpack_version'] = $this->get_jetpack_version();
|
||||
|
||||
if ( $main_network_site = $this->main_network_site() ) {
|
||||
$options['main_network_site'] = (string) rtrim( $main_network_site, '/' );
|
||||
}
|
||||
|
||||
if ( is_array( $active_modules = Jetpack_Options::get_option( 'active_modules' ) ) ) {
|
||||
$options['active_modules'] = (array) array_values( $active_modules );
|
||||
}
|
||||
|
||||
$options['software_version'] = (string) $this->wp_version();
|
||||
$options['max_upload_size'] = $this->max_upload_size();
|
||||
$options['wp_memory_limit'] = $this->wp_memory_limit();
|
||||
$options['wp_max_memory_limit'] = $this->wp_max_memory_limit();
|
||||
|
||||
// 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_multisite();
|
||||
|
||||
$file_mod_disabled_reasons = array_keys( array_filter( array(
|
||||
'automatic_updater_disabled' => (bool) $this->get_constant( 'AUTOMATIC_UPDATER_DISABLED' ),
|
||||
// WP AUTO UPDATE CORE defaults to minor, '1' if true and '0' if set to false.
|
||||
'wp_auto_update_core_disabled' => ! ( (bool) $this->get_constant( 'WP_AUTO_UPDATE_CORE' ) ),
|
||||
'is_version_controlled' => (bool) $this->is_version_controlled(),
|
||||
// By default we assume that site does have system write access if the value is not set yet.
|
||||
'has_no_file_system_write_access' => ! (bool) $this->file_system_write_access(),
|
||||
'disallow_file_mods' => (bool) $this->get_constant( 'DISALLOW_FILE_MODS' ),
|
||||
) ) );
|
||||
|
||||
$options['file_mod_disabled'] = empty( $file_mod_disabled_reasons ) ? false : $file_mod_disabled_reasons;
|
||||
}
|
||||
|
||||
function get_jetpack_modules() {
|
||||
return array_values( Jetpack_Options::get_option( 'active_modules', array() ) );
|
||||
}
|
||||
|
||||
function is_module_active( $module ) {
|
||||
return in_array ( $module, Jetpack_Options::get_option( 'active_modules', array() ), true );
|
||||
}
|
||||
|
||||
function is_vip() {
|
||||
return false; // this may change for VIP Go sites, which sync using Jetpack
|
||||
}
|
||||
|
||||
function featured_images_enabled() {
|
||||
return $this->current_theme_supports( 'post-thumbnails' );
|
||||
}
|
||||
|
||||
function get_post_formats() {
|
||||
// deprecated - see separate endpoint. get a list of supported post formats
|
||||
$all_formats = get_post_format_strings();
|
||||
$supported = $this->get_theme_support( 'post-formats' );
|
||||
|
||||
$supported_formats = array();
|
||||
|
||||
if ( isset( $supported[0] ) ) {
|
||||
foreach ( $supported[0] as $format ) {
|
||||
$supported_formats[ $format ] = $all_formats[ $format ];
|
||||
}
|
||||
}
|
||||
|
||||
return $supported_formats;
|
||||
}
|
||||
|
||||
function get_icon() {
|
||||
$icon_id = get_option( 'site_icon' );
|
||||
if ( empty( $icon_id ) ) {
|
||||
$icon_id = Jetpack_Options::get_option( 'site_icon_id' );
|
||||
}
|
||||
|
||||
if ( empty( $icon_id ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$icon = array_filter( array(
|
||||
'img' => wp_get_attachment_image_url( $icon_id, 'full' ),
|
||||
'ico' => wp_get_attachment_image_url( $icon_id, array( 16, 16 ) )
|
||||
) );
|
||||
|
||||
if ( empty( $icon ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( current_user_can( 'edit_posts', $icon_id ) ) {
|
||||
$icon['media_id'] = (int) $icon_id;
|
||||
}
|
||||
|
||||
return $icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private methods
|
||||
**/
|
||||
|
||||
private function is_main_site( $response ) {
|
||||
if ( isset( $response['options']->main_network_site, $response['options']->unmapped_url ) ) {
|
||||
$main_network_site_url = set_url_scheme( $response['options']->main_network_site, 'http' );
|
||||
$unmapped_url = set_url_scheme( $response['options']->unmapped_url, 'http' );
|
||||
if ( $unmapped_url === $main_network_site_url ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// For Jetpack sites this will always return false
|
||||
protected function is_a8c_publication( $post_id ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
198
wp-content/plugins/jetpack/sal/class.json-api-site-jetpack.php
Normal file
198
wp-content/plugins/jetpack/sal/class.json-api-site-jetpack.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
use Automattic\Jetpack\Sync\Functions;
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class.json-api-site-jetpack-base.php';
|
||||
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 );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function main_network_site() {
|
||||
return network_site_url();
|
||||
}
|
||||
|
||||
protected function wp_version() {
|
||||
global $wp_version;
|
||||
return $wp_version;
|
||||
}
|
||||
|
||||
protected function max_upload_size() {
|
||||
return wp_max_upload_size();
|
||||
}
|
||||
|
||||
protected function wp_memory_limit() {
|
||||
return wp_convert_hr_to_bytes( WP_MEMORY_LIMIT );
|
||||
}
|
||||
|
||||
protected function wp_max_memory_limit() {
|
||||
return wp_convert_hr_to_bytes( WP_MAX_MEMORY_LIMIT );
|
||||
}
|
||||
|
||||
protected function is_main_network() {
|
||||
return Jetpack::is_multi_network();
|
||||
}
|
||||
|
||||
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() {
|
||||
return Functions::is_version_controlled();
|
||||
}
|
||||
|
||||
protected function file_system_write_access() {
|
||||
return Functions::file_system_write_access();
|
||||
}
|
||||
|
||||
protected function current_theme_supports( $feature_name ) {
|
||||
return current_theme_supports( $feature_name );
|
||||
}
|
||||
|
||||
protected function get_theme_support( $feature_name ) {
|
||||
return get_theme_support( $feature_name );
|
||||
}
|
||||
|
||||
public function get_updates() {
|
||||
return (array) Jetpack::get_updates();
|
||||
}
|
||||
|
||||
function get_id() {
|
||||
return $this->platform->token->blog_id;
|
||||
}
|
||||
|
||||
function has_videopress() {
|
||||
// TODO - this only works on wporg site - need to detect videopress option for remote Jetpack site on WPCOM
|
||||
$videopress = Jetpack_Options::get_option( 'videopress', array() );
|
||||
if ( isset( $videopress['blog_id'] ) && $videopress['blog_id'] > 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function upgraded_filetypes_enabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function is_mapped_domain() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function is_redirect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function is_following() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function has_wordads() {
|
||||
return Jetpack::is_module_active( 'wordads' );
|
||||
}
|
||||
|
||||
function get_frame_nonce() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_jetpack_frame_nonce() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function is_headstart_fresh() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function allowed_file_types() {
|
||||
$allowed_file_types = array();
|
||||
|
||||
// http://codex.wordpress.org/Uploading_Files
|
||||
$mime_types = get_allowed_mime_types();
|
||||
foreach ( $mime_types as $type => $mime_type ) {
|
||||
$extras = explode( '|', $type );
|
||||
foreach ( $extras as $extra ) {
|
||||
$allowed_file_types[] = $extra;
|
||||
}
|
||||
}
|
||||
|
||||
return $allowed_file_types;
|
||||
}
|
||||
|
||||
function is_private() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_plan() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_subscribers_count() {
|
||||
return 0; // special magic fills this in on the WPCOM side
|
||||
}
|
||||
|
||||
function get_capabilities() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_locale() {
|
||||
return get_bloginfo( 'language' );
|
||||
}
|
||||
|
||||
function is_jetpack() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_jetpack_version() {
|
||||
return JETPACK__VERSION;
|
||||
}
|
||||
|
||||
function get_ak_vp_bundle_enabled() {}
|
||||
|
||||
function get_jetpack_seo_front_page_description() {
|
||||
return Jetpack_SEO_Utils::get_front_page_meta_description();
|
||||
}
|
||||
|
||||
function get_jetpack_seo_title_formats() {
|
||||
return Jetpack_SEO_Titles::get_custom_title_formats();
|
||||
}
|
||||
|
||||
function get_verification_services_codes() {
|
||||
return get_option( 'verification_services_codes', null );
|
||||
}
|
||||
|
||||
function get_podcasting_archive() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function is_connected_site() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function current_user_can( $role ) {
|
||||
return current_user_can( $role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post functions
|
||||
*/
|
||||
|
||||
function wrap_post( $post, $context ) {
|
||||
return new Jetpack_Post( $this, $post, $context );
|
||||
}
|
||||
|
||||
}
|
||||
60
wp-content/plugins/jetpack/sal/class.json-api-token.php
Normal file
60
wp-content/plugins/jetpack/sal/class.json-api-token.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* So that we have a real class instead of just passing around an array
|
||||
*/
|
||||
class SAL_Token {
|
||||
|
||||
public $blog_id;
|
||||
public $user_id;
|
||||
public $scope;
|
||||
public $client_id;
|
||||
public $external_user_id;
|
||||
public $external_user_code;
|
||||
public $auth_type;
|
||||
|
||||
function __construct( $blog_id, $user_id, $scope, $client_id, $external_user_id, $external_user_code, $auth_type ) {
|
||||
$this->blog_id = $blog_id; // if blog_id is set and scope is not global, limit to that blog
|
||||
$this->user_id = $user_id;
|
||||
$this->client_id = $client_id;
|
||||
$this->scope = $scope;
|
||||
$this->external_user_id = $external_user_id;
|
||||
$this->external_user_code = $external_user_code;
|
||||
$this->auth_type = $auth_type;
|
||||
}
|
||||
|
||||
public function is_global() {
|
||||
return $scope === 'global';
|
||||
}
|
||||
|
||||
static function for_anonymous_user() {
|
||||
return new SAL_Token(
|
||||
null,
|
||||
get_current_user_id(),
|
||||
null, // there's only ever one scope in our current API implementation, auth or global
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
static function from_rest_token( $token ) {
|
||||
$user_id = isset( $token['user_id'] ) ? $token['user_id'] : get_current_user_id();
|
||||
$scope = isset( $token['scope'] ) ? $token['scope'][0] : null;
|
||||
$client_id = isset( $token['client_id'] ) ? $token['client_id'] : null;
|
||||
$external_user_id = isset( $token['external_user_id'] ) ? $token['external_user_id'] : null;
|
||||
$external_user_code = isset( $token['external_user_code'] ) ? $token['external_user_code'] : null;
|
||||
$auth = isset( $token['auth'] ) ? $token['auth'] : null;
|
||||
|
||||
return new SAL_Token(
|
||||
$token['blog_id'],
|
||||
$user_id,
|
||||
$scope, // there's only ever one scope in our current API implementation, auth or global
|
||||
$client_id,
|
||||
$external_user_id,
|
||||
$external_user_code,
|
||||
$auth
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user