function callback($path = '', $blog_id = 0) { $blog_id = $this->api->switch_to_blog_and_validate_user($this->api->get_blog_id($blog_id)); if (is_wp_error($blog_id)) { return $blog_id; } if (!current_user_can('edit_posts')) { return new WP_Error('unauthorized', 'Your token must have permission to post on this blog.', 403); } $args = $this->query_args(); $shortcode = trim($args['shortcode']); // Quick validation - shortcodes should always be enclosed in brackets [] if (!wp_startswith($shortcode, '[') || !wp_endswith($shortcode, ']')) { return new WP_Error('invalid_shortcode', 'The shortcode parameter must begin and end with square brackets.', 400); } // Make sure only one shortcode is being rendered at a time $pattern = get_shortcode_regex(); preg_match_all("/{$pattern}/s", $shortcode, $matches); if (count($matches[0]) > 1) { return new WP_Error('invalid_shortcode', 'Only one shortcode can be rendered at a time.', 400); } $render = $this->process_render(array($this, 'do_shortcode'), $shortcode); // if nothing happened, then the shortcode does not exist. if ($shortcode == $render['result']) { return new WP_Error('invalid_shortcode', 'The requested shortcode does not exist.', 400); } // our output for this endpoint.. $return['shortcode'] = $shortcode; $return['result'] = $render['result']; $return = $this->add_assets($return, $render['loaded_scripts'], $render['loaded_styles']); return $return; }
protected function validate_themes() { if (empty($this->themes) || !is_array($this->themes)) { return new WP_Error('missing_themes', __('No themes found.', 'jetpack')); } foreach ($this->themes as $index => $theme) { if (self::is_installed_theme($theme)) { return new WP_Error('theme_already_installed', __('The theme is already installed', 'jetpack')); } if (wp_endswith($theme, '-wpcom')) { $file = self::download_wpcom_theme_to_file($theme); if (is_wp_error($file)) { return $file; } $this->download_links[$theme] = $file; continue; } $params = (object) array('slug' => $theme); $url = 'https://api.wordpress.org/themes/info/1.0/'; $args = array('body' => array('action' => 'theme_information', 'request' => serialize($params))); $response = wp_remote_post($url, $args); $theme_data = unserialize($response['body']); if (is_wp_error($theme_data)) { return $theme_data; } if (!is_object($theme_data) && !isset($theme_data->download_link)) { return new WP_Error('theme_not_found', __('This theme does not exist', 'jetpack'), 404); } $this->download_links[$theme] = $theme_data->download_link; } return true; }
function wpcom_amp_extract_image_dimensions_from_querystring($dimensions, $url) { if (is_array($dimensions)) { return $dimensions; } $host = parse_url($url, PHP_URL_HOST); if (!wp_endswith($host, '.wp.com') || !wp_endswith($host, '.files.wordpress.com')) { return false; } $query = parse_url($url, PHP_URL_QUERY); $w = isset($query['w']) ? absint($query['w']) : false; $h = isset($query['h']) ? absint($query['h']) : false; if (false !== $w && false !== $h) { return array($w, $h); } return false; }
function wpcom_amp_extract_image_dimensions_from_querystring($dimensions) { foreach ($dimensions as $url => $value) { if (is_array($value)) { continue; } $host = parse_url($url, PHP_URL_HOST); if (!wp_endswith($host, '.wp.com') || !wp_endswith($host, '.files.wordpress.com')) { continue; } $query = parse_url($url, PHP_URL_QUERY); $w = isset($query['w']) ? absint($query['w']) : false; $h = isset($query['h']) ? absint($query['h']) : false; if (false !== $w && false !== $h) { $dimensions[$url] = array('width' => $w, 'height' => $h); } } return $dimensions; }
/** * 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 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 * @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; if (!$closest_endpoint_cache) { $closest_endpoint_cache = array(); } 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')) { return $closest_endpoint_cache[$template_path][$request_method] = $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; } } } $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, (object) array('version' => $this->api->version, 'regex' => $endpoint_path_regex)); return $closest_endpoint_cache[$template_path][$request_method] = $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, (object) $max_version_found); return $max_version_found['version']; } // Otherwise, use the API version of the current request return $this->api->version; }
protected function validate_themes() { if (empty($this->themes) || !is_array($this->themes)) { return new WP_Error('missing_themes', __('No themes found.', 'jetpack')); } foreach ($this->themes as $index => $theme) { if (self::is_installed_theme($theme)) { return new WP_Error('theme_already_installed', __('The theme is already installed', 'jetpack')); } /** * Filters whether to skip the standard method of downloading and validating a WordPress.com * theme. An alternative method of WPCom theme download and validation can be * executed during the filter. * * The filter can also return an instance of WP_Error; in which case the endpoint response will * contain this error. * * @module json-api * * @since 4.4.2 * * @param bool $skip_download_filter_result Whether to skip the standard method of downloading * and validating a WPCom theme. * @param string $theme_slug Theme name (slug). If it is a WPCom theme, * it should be suffixed with `-wpcom`. */ $skip_download_filter_result = apply_filters('jetpack_wpcom_theme_skip_download', false, $theme); if (is_wp_error($skip_download_filter_result)) { return $skip_download_filter_result; } elseif ($skip_download_filter_result) { continue; } if (wp_endswith($theme, '-wpcom')) { $file = self::download_wpcom_theme_to_file($theme); if (is_wp_error($file)) { return $file; } $this->download_links[$theme] = $file; continue; } $params = (object) array('slug' => $theme); $url = 'https://api.wordpress.org/themes/info/1.0/'; $args = array('body' => array('action' => 'theme_information', 'request' => serialize($params))); $response = wp_remote_post($url, $args); $theme_data = unserialize($response['body']); if (is_wp_error($theme_data)) { return $theme_data; } if (!is_object($theme_data) && !isset($theme_data->download_link)) { return new WP_Error('theme_not_found', __('This theme does not exist', 'jetpack'), 404); } $this->download_links[$theme] = $theme_data->download_link; } return true; }