/** * Retrieve the current event queue * * @subcommand get-queue */ public function get_queue($args, $assoc_args) { // Build and make request $queue_request = new \WP_REST_Request('POST', '/' . \Automattic\WP\Cron_Control\REST_API::API_NAMESPACE . '/' . \Automattic\WP\Cron_Control\REST_API::ENDPOINT_LIST); $queue_request->add_header('Content-Type', 'application/json'); $queue_request->set_body(wp_json_encode(array('secret' => \WP_CRON_CONTROL_SECRET))); $queue_request = rest_do_request($queue_request); // Oh well if ($queue_request->is_error()) { \WP_CLI::error($queue_request->as_error()->get_error_message()); } // Get the decoded JSON object returned by the API $queue_response = $queue_request->get_data(); // No events, nothing more to do if (empty($queue_response['events'])) { \WP_CLI::warning(__('No events in the current queue', 'automattic-cron-control')); return; } // Prepare items for display $events_for_display = $this->format_events($queue_response['events']); $total_events_to_display = count($events_for_display); \WP_CLI::line(sprintf(_n('Displaying one event', 'Displaying %s events', $total_events_to_display, 'automattic-cron-control'), number_format_i18n($total_events_to_display))); // And reformat $format = 'table'; if (isset($assoc_args['format'])) { if ('ids' === $assoc_args['format']) { \WP_CLI::error(__('Invalid output format requested', 'automattic-cron-control')); } else { $format = $assoc_args['format']; } } \WP_CLI\Utils\format_items($format, $events_for_display, array('timestamp', 'action', 'instance', 'scheduled_for', 'internal_event', 'schedule_name', 'event_args')); }
function page_admin_scripts() { if ($this->is_redirecting) { return; // No need for scripts on a fallback page } $is_dev_mode = Jetpack::is_development_mode(); // Enqueue jp.js and localize it wp_enqueue_script('react-plugin', plugins_url('_inc/build/admin.js', JETPACK__PLUGIN_FILE), array(), JETPACK__VERSION, true); if (!$is_dev_mode) { // Required for Analytics wp_enqueue_script('jp-tracks', '//stats.wp.com/w.js', array(), gmdate('YW'), true); } $localeSlug = explode('_', get_locale()); $localeSlug = $localeSlug[0]; // Collecting roles that can view site stats $stats_roles = array(); $enabled_roles = function_exists('stats_get_option') ? stats_get_option('roles') : array('administrator'); foreach (get_editable_roles() as $slug => $role) { $stats_roles[$slug] = array('name' => translate_user_role($role['name']), 'canView' => is_array($enabled_roles) ? in_array($slug, $enabled_roles, true) : false); } $response = rest_do_request(new WP_REST_Request('GET', '/jetpack/v4/module/all')); $modules = $response->get_data(); // Preparing translated fields for JSON encoding by transforming all HTML entities to // respective characters. foreach ($modules as $slug => $data) { $modules[$slug]['name'] = html_entity_decode($data['name']); $modules[$slug]['description'] = html_entity_decode($data['description']); $modules[$slug]['short_description'] = html_entity_decode($data['short_description']); $modules[$slug]['long_description'] = html_entity_decode($data['long_description']); } // Add objects to be passed to the initial state of the app wp_localize_script('react-plugin', 'Initial_State', array('WP_API_root' => esc_url_raw(rest_url()), 'WP_API_nonce' => wp_create_nonce('wp_rest'), 'pluginBaseUrl' => plugins_url('', JETPACK__PLUGIN_FILE), 'connectionStatus' => array('isActive' => Jetpack::is_active(), 'isStaging' => Jetpack::is_staging_site(), 'devMode' => array('isActive' => $is_dev_mode, 'constant' => defined('JETPACK_DEV_DEBUG') && JETPACK_DEV_DEBUG, 'url' => site_url() && false === strpos(site_url(), '.'), 'filter' => apply_filters('jetpack_development_mode', false)), 'isPublic' => '1' == get_option('blog_public'), 'isInIdentityCrisis' => Jetpack::validate_sync_error_idc_option()), 'dismissedNotices' => $this->get_dismissed_jetpack_notices(), 'isDevVersion' => Jetpack::is_development_version(), 'currentVersion' => JETPACK__VERSION, 'happinessGravIds' => jetpack_get_happiness_gravatar_ids(), 'getModules' => $modules, 'showJumpstart' => jetpack_show_jumpstart(), 'rawUrl' => Jetpack::build_raw_urls(get_home_url()), 'adminUrl' => esc_url(admin_url()), 'stats' => array('data' => array('general' => false, 'day' => false, 'week' => false, 'month' => false), 'roles' => $stats_roles), 'settingNames' => array('jetpack_holiday_snow_enabled' => function_exists('jetpack_holiday_snow_option_name') ? jetpack_holiday_snow_option_name() : false), 'userData' => array('currentUser' => jetpack_current_user_data()), 'locale' => $this->get_i18n_data(), 'localeSlug' => $localeSlug, 'jetpackStateNotices' => array('messageCode' => Jetpack::state('message'), 'errorCode' => Jetpack::state('error'), 'errorDescription' => Jetpack::state('error_description')), 'tracksUserData' => Jetpack_Tracks_Client::get_connected_user_tracks_identity(), 'currentIp' => function_exists('jetpack_protect_get_ip') ? jetpack_protect_get_ip() : false)); }
/** * Delete a single post. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error */ public function delete_item($request) { $id = (int) $request['id']; $force = (bool) $request['force']; $post = get_post($id); if (empty($id) || empty($post->ID) || $this->post_type !== $post->post_type) { return new WP_Error('rest_post_invalid_id', __('Invalid post id.'), array('status' => 404)); } $supports_trash = EMPTY_TRASH_DAYS > 0; if ($post->post_type === 'attachment') { $supports_trash = $supports_trash && MEDIA_TRASH; } /** * Filter whether a post is trashable. * * Return false to disable trash support for the post. * * @param boolean $supports_trash Whether the post type support trashing. * @param WP_Post $post The Post object being considered for trashing support. */ $supports_trash = apply_filters('rest_post_trashable', $supports_trash, $post); if (!$this->check_delete_permission($post)) { return new WP_Error('rest_user_cannot_delete_post', __('Sorry, you are not allowed to delete this post.'), array('status' => rest_authorization_required_code())); } $request = new WP_REST_Request('GET', '/wp/v2/' . $this->get_post_type_base($this->post_type) . '/' . $post->ID); $request->set_param('context', 'edit'); $response = rest_do_request($request); // If we're forcing, then delete permanently. if ($force) { $result = wp_delete_post($id, true); $status = 'deleted'; } else { // If we don't support trashing for this type, error out. if (!$supports_trash) { return new WP_Error('rest_trash_not_supported', __('The post does not support trashing.'), array('status' => 501)); } // Otherwise, only trash if we haven't already. if ('trash' === $post->post_status) { return new WP_Error('rest_already_deleted', __('The post has already been deleted.'), array('status' => 410)); } // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) $result = wp_trash_post($id); $status = 'trashed'; } if (!$result) { return new WP_Error('rest_cannot_delete', __('The post cannot be deleted.'), array('status' => 500)); } $data = $response->get_data(); $data = array('data' => $data, $status => true); $response->set_data($data); /** * Fires after a single post is deleted or trashed via the REST API. * * @param object $post The deleted or trashed post. * @param array $data The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action('rest_delete_post', $post, $data, $request); return $response; }
/** * Checks the site plan and deactivates modules that were active but are no longer included in the plan. * * @since 4.4.0 * * @param $page * * @return bool|array */ function check_plan_deactivate_modules($page) { if (Jetpack::is_development_mode() || !in_array($page->base, array('toplevel_page_jetpack', 'admin_page_jetpack_modules', 'jetpack_page_vaultpress', 'jetpack_page_stats', 'jetpack_page_akismet-key-config')) || true === self::$plan_checked) { return false; } self::$plan_checked = true; $previous = get_option('jetpack_active_plan', ''); $response = rest_do_request(new WP_REST_Request('GET', '/jetpack/v4/site')); if (!is_object($response) || $response->is_error()) { // If we can't get information about the current plan we don't do anything self::$plan_checked = true; return; } $current = $response->get_data(); $current = json_decode($current['data']); $to_deactivate = array(); if (isset($current->plan->product_slug)) { if (empty($previous) || !isset($previous['product_slug']) || $previous['product_slug'] !== $current->plan->product_slug) { $active = Jetpack::get_active_modules(); switch ($current->plan->product_slug) { case 'jetpack_free': $to_deactivate = array('seo-tools', 'videopress'); break; case 'jetpack_personal': case 'jetpack_personal_monthly': $to_deactivate = array('seo-tools', 'videopress'); break; case 'jetpack_premium': case 'jetpack_premium_monthly': $to_deactivate = array('seo-tools'); break; } $to_deactivate = array_intersect($active, $to_deactivate); if (!empty($to_deactivate)) { Jetpack::update_active_modules(array_filter(array_diff($active, $to_deactivate))); } } } return array('previous' => $previous, 'current' => $current, 'deactivate' => $to_deactivate); }
/** * Delete a single post * * @param WP_REST_Request $request Full details about the request * @return array|WP_Error */ public function delete_item($request) { $id = (int) $request['id']; $force = (bool) $request['force']; $post = get_post($id); if (empty($id) || empty($post->ID) || $this->post_type !== $post->post_type) { return new WP_Error('rest_post_invalid_id', __('Invalid post ID.'), array('status' => 404)); } $supports_trash = EMPTY_TRASH_DAYS > 0; if ($post->post_type === 'attachment') { $supports_trash = $supports_trash && MEDIA_TRASH; } /** * Filter whether the post type supports trashing. * * @param boolean $supports_trash Does the post type support trashing? * @param WP_Post $post Post we're attempting to trash. */ $supports_trash = apply_filters('rest_post_type_trashable', $supports_trash, $post); if (!$this->check_delete_permission($post)) { return new WP_Error('rest_user_cannot_delete_post', __('Sorry, you are not allowed to delete this post.'), array('status' => 401)); } $request = new WP_REST_Request('GET', '/wp/v2/' . $this->get_post_type_base($this->post_type) . '/' . $post->ID); $request->set_param('context', 'edit'); $response = rest_do_request($request); // If we're forcing, then delete permanently if ($force) { $result = wp_delete_post($id, true); } else { // If we don't support trashing for this type, error out if (!$supports_trash) { return new WP_Error('rest_trash_not_supported', __('The post does not support trashing.'), array('status' => 501)); } // Otherwise, only trash if we haven't already if ('trash' === $post->post_status) { return new WP_Error('rest_already_deleted', __('The post has already been deleted.'), array('status' => 410)); } // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) $result = wp_trash_post($id); } if (!$result) { return new WP_Error('rest_cannot_delete', __('The post cannot be deleted.'), array('status' => 500)); } return $response; }
/** * Do a REST Request * * @param string $method * */ private function do_request($method, $route, $assoc_args) { if ('internal' === $this->scope) { $request = new \WP_REST_Request($method, $route); if (in_array($method, array('POST', 'PUT'))) { $request->set_body_params($assoc_args); } else { foreach ($assoc_args as $key => $value) { $request->set_param($key, $value); } } $response = rest_do_request($request); if ($error = $response->as_error()) { WP_CLI::error($error); } return array($response->get_status(), $response->get_data(), $response->get_headers()); } else { if ('http' === $this->scope) { $response = Utils\http_request($method, rtrim($this->api_url, '/') . $route, $assoc_args); $body = json_decode($response->body, true); if ($response->status_code >= 400) { if (!empty($body['message'])) { WP_CLI::error($body['message'] . ' ' . json_encode(array('status' => $response->status_code))); } else { switch ($response->status_code) { case 404: WP_CLI::error("No {$this->name} found."); break; default: WP_CLI::error('Could not complete request.'); break; } } } return array($response->status_code, json_decode($response->body, true), $response->headers); } } WP_CLI::error('Invalid scope for REST command.'); }
/** * Do a REST Request * * @param string $method * */ private function do_request($method, $route, $assoc_args) { if (!defined('REST_REQUEST')) { define('REST_REQUEST', true); } $request = new WP_REST_Request($method, $route); if (in_array($method, array('POST', 'PUT'))) { $request->set_body_params($assoc_args); } else { foreach ($assoc_args as $key => $value) { $request->set_param($key, $value); } } if (defined('SAVEQUERIES') && SAVEQUERIES) { $original_queries = is_array($GLOBALS['wpdb']->queries) ? array_keys($GLOBALS['wpdb']->queries) : array(); } $response = rest_do_request($request); if (defined('SAVEQUERIES') && SAVEQUERIES) { $performed_queries = array(); foreach ((array) $GLOBALS['wpdb']->queries as $key => $query) { if (in_array($key, $original_queries)) { continue; } $performed_queries[] = $query; } usort($performed_queries, function ($a, $b) { if ($a[1] === $b[1]) { return 0; } return $a[1] > $b[1] ? -1 : 1; }); $query_count = count($performed_queries); $query_total_time = 0; foreach ($performed_queries as $query) { $query_total_time += $query[1]; } $slow_query_message = ''; if ($performed_queries && 'wc' === WP_CLI::get_config('debug')) { $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL; foreach ($performed_queries as $i => $query) { $i++; $bits = explode(', ', $query[2]); $backtrace = implode(', ', array_slice($bits, 13)); $seconds = round($query[1], 6); $slow_query_message .= <<<EOT {$i}: - {$seconds} seconds - {$backtrace} - {$query[0]} EOT; $slow_query_message .= PHP_EOL; } } elseif ('wc' !== WP_CLI::get_config('debug')) { $slow_query_message = '. Use --debug=wc to see all queries.'; } $query_total_time = round($query_total_time, 6); WP_CLI::debug("wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc'); } if ($error = $response->as_error()) { WP_CLI::error($error); } return array($response->get_status(), $response->get_data(), $response->get_headers()); }