/** * List all metadata associated with an object. * * <id> * : ID for the object. * * [--keys=<keys>] * : Limit output to metadata of specific keys. * * [--fields=<fields>] * : Limit the output to specific row fields. Defaults to id,meta_key,meta_value. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * @subcommand list */ public function list_($args, $assoc_args) { list($object_id) = $args; $keys = !empty($assoc_args['keys']) ? explode(',', $assoc_args['keys']) : array(); $metadata = get_metadata($this->meta_type, $object_id); if (!$metadata) { $metadata = array(); } $items = array(); foreach ($metadata as $key => $values) { // Skip if not requested if (!empty($keys) && !in_array($key, $keys)) { continue; } foreach ($values as $item_value) { $item_value = maybe_unserialize($item_value); if ((empty($assoc_args['format']) || in_array($assoc_args['format'], array('table', 'csv'))) && (is_object($item_value) || is_array($item_value))) { $item_value = json_encode($item_value); } $items[] = (object) array("{$this->meta_type}_id" => $object_id, 'meta_key' => $key, 'meta_value' => $item_value); } } if (!empty($assoc_args['fields'])) { $fields = explode(',', $assoc_args['fields']); } else { $fields = $this->get_fields(); } $formatter = new \WP_CLI\Formatter($assoc_args, $fields, $this->meta_type); $formatter->display_items($items); }
/** * List registered sidebars. * * ## OPTIONS * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each sidebar: * * * name * * id * * description * * These fields are optionally available: * * * class * * before_widget * * after_widget * * before_title * * after_title * * ## EXAMPLES * * wp sidebar list --fields=name,id --format=csv * * @subcommand list */ public function list_($args, $assoc_args) { global $wp_registered_sidebars; \WP_CLI\Utils\wp_register_unused_sidebar(); $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($wp_registered_sidebars); }
/** * List orphaned tables * * @subcommand list */ function list_orphaned_tables($args, $assoc_args) { $orphanTables = $this->get_orphan_tables(); $formatter = new \WP_CLI\Formatter($assoc_args, array('Orphaned Table Name')); $formatter->display_items($orphanTables); // Print a success message WP_CLI::success(sprintf("Found %d orphaned tables in the database.", count($orphanTables))); }
/** * List plugins a user has favorited in the WordPress.org plugins directory. * * ## OPTIONS * * <user> * : The username of the wordpress.org account whose favorite plugins you are listing. * * [--slug] * : Only return plugin slugs. Can be combined with `wp plugin install` (see examples). * * [--verbose] * : Display more information about the plugins. * * ## EXAMPLES * * wp plugin favorites matt * wp plugin favorites matt --verbose * wp plugin favorites matt --slug | xargs wp plugin install --activate * wp plugin favorites matt --slug | grep -vwE "(hello-dolly|bbpress)" | xargs wp plugin install --activate * * @synopsis <user> [--slug] [--verbose] */ public function __invoke($args, $assoc_args) { // prepare variables list($user) = $args; extract($assoc_args = wp_parse_args($assoc_args, array('slug' => false, 'verbose' => false))); // get access to plugins_api require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // query wordpress.org $api = plugins_api('query_plugins', array('user' => $user, 'fields' => array('last_updated' => true, 'active_installs' => true))); // only return slug? if ($slug) { foreach ($api->plugins as $plugin) { WP_CLI::log($plugin->slug); } return; } // get table columns $props = array('name', 'last_updated', 'rating', 'num_ratings', 'active_installs'); if ($verbose) { $props = array_merge($props, array('author', 'version', 'requires', 'tested', 'short_description')); } // pull object properties into an array $plugins = array(); foreach ($api->plugins as $plugin) { $args = array(); foreach ($props as $prop) { $args[$prop] = ''; if (isset($plugin->{$prop})) { $args[$prop] = $plugin->{$prop}; // clean up some fields for output switch ($prop) { case 'rating': $args[$prop] = (int) $args['rating'] / 100 * 5 . '/5'; break; case 'author': $args[$prop] = strip_tags($args['author']); break; case 'last_updated': $args[$prop] = date('Y-m-d', strtotime($args['last_updated'])); break; case 'active_installs': $args[$prop] = number_format($args['active_installs']); break; } } } $plugins[$plugin->slug] = $args; } if (!$plugins) { WP_CLI::log('No favorite plugins found.'); return; } // output as list table $formatter = new \WP_CLI\Formatter($assoc_args, $props, 'plugin'); $formatter->display_items($plugins); }
/** * List widgets associated with a sidebar. * * ## OPTIONS * * <sidebar-id> * : ID for the corresponding sidebar. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : Render output in a particular format. * --- * default: table * options: * - table * - csv * - ids * - json * - count * - yaml * --- * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each widget: * * * name * * id * * position * * options * * There are no optionally available fields. * * ## EXAMPLES * * $ wp widget list sidebar-1 --fields=name,id --format=csv * name,id * meta,meta-5 * search,search-3 * * @subcommand list */ public function list_($args, $assoc_args) { list($sidebar_id) = $args; $this->validate_sidebar($sidebar_id); $output_widgets = $this->get_sidebar_widgets($sidebar_id); if (!empty($assoc_args['format']) && 'ids' === $assoc_args['format']) { $output_widgets = wp_list_pluck($output_widgets, 'id'); } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($output_widgets); }
/** * List registered sidebars. * * ## OPTIONS * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : Render output in a particular format. * --- * default: table * options: * - table * - csv * - json * - ids * - count * - yaml * --- * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each sidebar: * * * name * * id * * description * * These fields are optionally available: * * * class * * before_widget * * after_widget * * before_title * * after_title * * ## EXAMPLES * * $ wp sidebar list --fields=name,id --format=csv * name,id * "Widget Area",sidebar-1 * "Inactive Widgets",wp_inactive_widgets * * @subcommand list */ public function list_($args, $assoc_args) { global $wp_registered_sidebars; \WP_CLI\Utils\wp_register_unused_sidebar(); if (!empty($assoc_args['format']) && 'ids' === $assoc_args['format']) { $sidebars = wp_list_pluck($wp_registered_sidebars, 'id'); } else { $sidebars = $wp_registered_sidebars; } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($sidebars); }
/** * Get information about the licensing add-on. */ public function info() { $settings = it_exchange_get_option('addon_itelic'); if ($settings['renewal-discount-type'] == 'percent') { $discount = $settings['renewal-discount-amount'] . '%'; } else { $discount = it_exchange_format_price($settings['renewal-discount-amount']); } $info = array('version' => ITELIC\Plugin::VERSION, 'online_software_enabled' => $settings['sell-online-software'] ? 'yes' : 'no', 'remote_activation_enabled' => $settings['enable-remote-activation'] ? 'yes' : 'no', 'remote_deactivation_enabled' => $settings['enable-remote-deactivation'] ? 'yes' : 'no', 'renewal_discounts_enabled' => $settings['enable-renewal-discounts'] ? 'yes' : 'no', 'renewal_discount' => $discount, 'renewal_discount_expiry' => sprintf("%d days", $settings['renewal-discount-expiry'])); $args = array('fields' => array_keys($info)); $formatter = new \WP_CLI\Formatter($args); $formatter->display_item($info); }
/** * List all roles. * * ## OPTIONS * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to name,role. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * * wp role list --fields=role --format=csv * * @subcommand list */ public function _list($args, $assoc_args) { global $wp_roles; $output_roles = array(); foreach ($wp_roles->roles as $key => $role) { $output_role = new stdClass(); $output_role->name = $role['name']; $output_role->role = $key; $output_roles[] = $output_role; } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($output_roles); }
/** * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. * * ## OPTIONS * * [--patch] * : Only list patch updates * * [--minor] * : Only list minor updates * * [--major] * : Only list major updates * * [--field=<field>] * : Prints the value of a single field for each update. * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * @subcommand check-update */ public function check_update($_, $assoc_args) { $updates = $this->get_updates($assoc_args); if ($updates) { $formatter = new \WP_CLI\Formatter($assoc_args, array('version', 'update_type', 'package_url')); $formatter->display_items($updates); } else { if (empty($assoc_args['format']) || 'table' == $assoc_args['format']) { $update_type = $this->get_update_type_str($assoc_args); WP_CLI::success("WP-CLI is at the latest{$update_type}version."); } } }
/** * See Status of a working job * * @param $args * @param $assoc_args */ public function working($args, $assoc_args) { $job_object = BackWPup_Job::get_working_data(); if (!is_object($job_object)) { WP_CLI::error(__('No job running', 'backwpup')); } $formatter_args = array('format' => 'table', 'fields' => array('JobID', 'Name', 'Warnings', 'Errors', 'On Step', 'Done'), 'field' => NULL); $formatter = new WP_CLI\Formatter($formatter_args); $items = array(); $items[] = array('JobID' => $job_object->job['jobid'], 'Name' => $job_object->job['name'], 'Warnings' => $job_object->warnings, 'Errors' => $job_object->errors, 'On Step' => $job_object->steps_data[$job_object->step_working]['NAME'], 'Done' => $job_object->step_percent . ' / ' . $job_object->substep_percent, 'Last message' => str_replace('…', '...', strip_tags($job_object->lastmsg))); $formatter->display_items($items); WP_CLI::log('Last Message: ' . str_replace('…', '...', strip_tags($job_object->lastmsg))); }
protected function format_output(array $response) { $headers = []; foreach ($response['headers'] as $header => $value) { if (is_array($value)) { $value = join("\n", $value); } $headers[] = compact('header', 'value'); } $args = (array) $this->args; $formatter = new \WP_CLI\Formatter($args, ['header', 'value']); ob_start(); $formatter->display_items($headers); return ob_get_clean(); }
/** * List widgets associated with a sidebar. * * <sidebar-id> * : ID for the corresponding sidebar. * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to name, id, description * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * * ## EXAMPLES * * wp sidebar widget list <sidebar-id> --fields=name --format=csv * * @subcommand list */ public function list_($args, $assoc_args) { list($sidebar_id) = $args; $this->validate_sidebar($sidebar_id); $output_widgets = $this->get_sidebar_widgets($sidebar_id); if (empty($assoc_args['format']) || in_array($assoc_args['format'], array('table', 'csv'))) { foreach ($output_widgets as &$output_widget) { $output_widget->options = json_encode($output_widget->options); } } if (!empty($assoc_args['format']) && 'ids' === $assoc_args['format']) { $output_widgets = wp_list_pluck($output_widgets, 'id'); } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($output_widgets); }
/** * Check for update via Version Check API. * * Lists the most recent versions when there are updates available, or success message when up to date. * * ## OPTIONS * * [--minor] * : Compare only the first two parts of the version number. * * [--major] * : Compare only the first part of the version number. * * [--field=<field>] * : Prints the value of a single field for each update. * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] * : Accepted values: table, csv, json. Default: table * * @subcommand check-update */ function check_update($_, $assoc_args) { global $wp_version; $versions_path = ABSPATH . 'wp-includes/version.php'; include $versions_path; $url = 'https://api.wordpress.org/core/stable-check/1.0/'; $options = array('timeout' => 30); $headers = array('Accept' => 'application/json'); $response = Utils\http_request('GET', $url, $headers, $options); if (!$response->success || 200 !== $response->status_code) { WP_CLI::error("Failed to get latest version."); } $release_data = json_decode($response->body); $release_versions = array_keys((array) $release_data); usort($release_versions, function ($a, $b) { return 1 === version_compare($a, $b); }); $locale = get_locale(); $current_parts = explode('.', $wp_version); $updates = array(); foreach ($release_versions as $release_version) { // don't list earliers versions if (\WP_CLI\Utils\wp_version_compare($release_version, '>=')) { continue; } $release_parts = explode('.', $release_version); $update_type = 'major'; if ($release_parts[0] === $current_parts[0] && $release_parts[1] === $current_parts[1]) { $update_type = 'minor'; } if (!(\WP_CLI\Utils\get_flag_value($assoc_args, 'minor') && 'minor' !== $update_type) && !(\WP_CLI\Utils\get_flag_value($assoc_args, 'major') && 'major' !== $update_type)) { $updates = $this->remove_same_minor_releases($release_parts, $updates); $updates[] = array('version' => $release_version, 'update_type' => $update_type, 'package_url' => $this->get_download_url($release_version, $locale)); } } if ($updates) { $updates = array_reverse($updates); $formatter = new \WP_CLI\Formatter($assoc_args, array('version', 'update_type', 'package_url')); $formatter->display_items($updates); } else { if (empty($assoc_args['format']) || 'table' == $assoc_args['format']) { WP_CLI::success("WordPress is at the latest version."); } } }
/** * List users with super admin capabilities. * * ## OPTIONS * * [--format=<format>] * : Render output in a particular format. * --- * default: list * options: * - list * - table * - csv * - json * - count * - yaml * --- * * ## EXAMPLES * * # List user with super-admin capabilities * $ wp super-admin list * supervisor * administrator * * @subcommand list */ public function _list($_, $assoc_args) { $super_admins = self::get_admins(); if ('list' === $assoc_args['format']) { foreach ($super_admins as $user_login) { WP_CLI::line($user_login); } } else { $output_users = array(); foreach ($super_admins as $user_login) { $output_user = new stdClass(); $output_user->user_login = $user_login; $output_users[] = $output_user; } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($output_users); } }
/** * List capabilities for a given role. * * ## OPTIONS * * <role> * : Key for the role. * * [--format=<format>] * : Render output in a particular format. * --- * default: list * options: * - list * - table * - csv * - json * - count * - yaml * --- * * ## EXAMPLES * * # Display alphabetical list of Contributor capabilities * $ wp cap list 'contributor' | sort * delete_posts * edit_posts * level_0 * level_1 * read * * @subcommand list */ public function list_($args, $assoc_args) { $role_obj = self::get_role($args[0]); if ('list' === $assoc_args['format']) { foreach (array_keys($role_obj->capabilities) as $cap) { WP_CLI::line($cap); } } else { $output_caps = array(); foreach (array_keys($role_obj->capabilities) as $cap) { $output_cap = new stdClass(); $output_cap->name = $cap; $output_caps[] = $output_cap; } $formatter = new \WP_CLI\Formatter($assoc_args, $this->fields); $formatter->display_items($output_caps); } }
/** * List locations for the current theme. * * ## OPTIONS * * [--format=<format>] * : Render output in a particular format. * --- * default: table * options: * - table * - csv * - json * - count * - yaml * - ids * --- * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each location: * * * name * * description * * ## EXAMPLES * * $ wp menu location list * +----------+-------------------+ * | location | description | * +----------+-------------------+ * | primary | Primary Menu | * | social | Social Links Menu | * +----------+-------------------+ * * @subcommand list */ public function list_($_, $assoc_args) { $locations = get_registered_nav_menus(); $location_objs = array(); foreach ($locations as $location => $description) { $location_obj = new \stdClass(); $location_obj->location = $location; $location_obj->description = $description; $location_objs[] = $location_obj; } $formatter = new \WP_CLI\Formatter($assoc_args, array('location', 'description')); if ('ids' == $formatter->format) { $ids = array_map(function ($o) { return $o->location; }, $location_objs); $formatter->display_items($ids); } else { $formatter->display_items($location_objs); } }
/** * List all sites in a multisite install. * * ## OPTIONS * * [--network=<id>] * : The network to which the sites belong. * * [--field=<field>] * : Prints the value of a single field for each site. * * [--fields=<fields>] * : Comma-separated list of fields to show. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * * # Output a simple list of site URLs * wp site list --field=url * * @subcommand list */ function _list($_, $assoc_args) { if (!is_multisite()) { WP_CLI::error('This is not a multisite install.'); } global $wpdb; if (isset($assoc_args['fields'])) { $assoc_args['fields'] = preg_split('/,[ \\t]*/', $assoc_args['fields']); } $defaults = array('format' => 'table', 'fields' => array('blog_id', 'url', 'last_updated', 'registered')); $assoc_args = array_merge($defaults, $assoc_args); $where = array(); if (isset($assoc_args['network'])) { $where['site_id'] = $assoc_args['network']; } $iterator_args = array('table' => $wpdb->blogs, 'where' => $where); $it = new \WP_CLI\Iterators\Table($iterator_args); $it = \WP_CLI\Utils\iterator_map($it, function ($blog) { $blog->url = $blog->domain . $blog->path; return $blog; }); $formatter = new \WP_CLI\Formatter($assoc_args, null, 'site'); $formatter->display_items($it); }
/** * Query a set of Stream records. * * ## OPTIONS * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--<field>=<value>] * : One or more args to pass to WP_Stream_Query. * * [--format=<format>] * : Accepted values: table, count, json, json_pretty, csv. Default: table * * ## AVAILABLE FIELDS TO QUERY * * You can build a query from these fields: * * * user_id * * user_id__in * * user_id__not_in * * user_role * * user_role__in * * user_role__not_in * * date * * date_from * * date_to * * date_after * * date_before * * ip * * ip__in * * ip__not_in * * connector * * connector__in * * connector__not_in * * context * * context__in * * context__not_in * * action * * action__in * * action__not_in * * search * * search_field * * record * * record__in * * record__not_in * * records_per_page * * paged * * order * * orderby * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each post: * * * created * * ip * * user_id * * user_role * * summary * * These fields are optionally available: * * * ID * * site_id * * blog_id * * object_id * * connector * * context * * action * * ## EXAMPLES * * wp stream query --user_role__not_in=administrator --date_after=2015-01-01T12:00:00 * wp stream query --user_id=1 --action=login --records_per_page=50 --fields=created * * @see WP_Stream_Query * @see https://github.com/wp-stream/stream/wiki/WP-CLI-Command * @see https://github.com/wp-stream/stream/wiki/Query-Reference */ public function query($args, $assoc_args) { unset($args); $query_args = array(); $formatted_records = array(); $this->connection(); if (empty($assoc_args['fields'])) { $fields = array('created', 'ip', 'user_id', 'user_role', 'summary'); } else { $fields = explode(',', $assoc_args['fields']); } foreach ($assoc_args as $key => $value) { if ('format' === $key) { continue; } $query_args[$key] = $value; } $query_args['fields'] = implode(',', $fields); $records = wp_stream_get_instance()->db->query->query($query_args); // Make structure Formatter compatible foreach ((array) $records as $key => $record) { $formatted_records[$key] = array(); // Catch any fields missing in records foreach ($fields as $field) { if (!array_key_exists($field, $record)) { $record->{$field} = null; } } foreach ($record as $field_name => $field) { $formatted_records[$key] = array_merge($formatted_records[$key], $this->format_field($field_name, $field)); } } if (isset($assoc_args['format']) && 'table' !== $assoc_args['format']) { if ('count' === $assoc_args['format']) { WP_CLI::line(count($records)); } if ('json' === $assoc_args['format']) { WP_CLI::line(wp_stream_json_encode($formatted_records)); } if ('json_pretty' === $assoc_args['format']) { if (version_compare(PHP_VERSION, '5.4', '<')) { WP_CLI::line(wp_stream_json_encode($formatted_records)); // xss ok } else { WP_CLI::line(wp_stream_json_encode($formatted_records, JSON_PRETTY_PRINT)); // xss ok } } if ('csv' === $assoc_args['format']) { WP_CLI::line($this->csv_format($formatted_records)); } return; } $formatter = new \WP_CLI\Formatter($assoc_args, $fields); $formatter->display_items($formatted_records); }
/** * List options. * * [--search=<pattern>] * : Use wildcards ( * and ? ) to match option name. * * [--autoload=<value>] * : Match only autoload options when value is on, and only not-autoload option when off. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. Accepted values: table, json, csv, count, total_bytes. Default: table * * ## EXAMPLES * * # Get the total size of all autoload options * wp option list --autoload=on --format=total_bytes * * # Find biggest transients * wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail * * # List all options begining with "i2f_" * wp option list --search "i2f_*" * * ## AVAILABLE FIELDS * * This field will be displayed by default for each matching option: * * * option_name * * option_value * * These fields are optionally available: * * * autoload * * size_bytes * * @subcommand list */ public function list_($args, $assoc_args) { global $wpdb; $pattern = '%'; $fields = array('option_name', 'option_value'); $size_query = ",LENGTH(option_value) AS `size_bytes`"; $autoload_query = ''; if (isset($assoc_args['search'])) { $pattern = self::esc_like($assoc_args['search']); // substitute wildcards $pattern = str_replace('*', '%', $pattern); $pattern = str_replace('?', '_', $pattern); } if (isset($assoc_args['fields'])) { $fields = explode(',', $assoc_args['fields']); } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { $fields = array('size_bytes'); $size_query = ",SUM(LENGTH(option_value)) AS `size_bytes`"; } if (isset($assoc_args['autoload'])) { if ('on' === $assoc_args['autoload']) { $autoload_query = " AND autoload='yes'"; } elseif ('off' === $assoc_args['autoload']) { $autoload_query = " AND autoload='no'"; } else { WP_CLI::error("Value of '--autoload' should be on or off."); } } $results = $wpdb->get_results($wpdb->prepare("SELECT `option_name`,`option_value`,`autoload`" . $size_query . " FROM `{$wpdb->options}` WHERE `option_name` LIKE %s" . $autoload_query, $pattern)); if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { WP_CLI::line($results[0]->size_bytes); } else { $formatter = new \WP_CLI\Formatter($assoc_args, $fields); $formatter->display_items($results); } }
/** * Provide details on the Redis connection. * * ## OPTIONS * * [--reset] * : Reset Redis stats. Only affects `lifetime_hitrate` currently. * * [--field=<field>] * : Get the value of a particular field. * * [--format=<format>] * : Render results in a particular format. * --- * default: table * options: * - table * - json * - yaml * --- * * ## EXAMPLES * * $ wp redis info * +-------------------+-----------+ * | Field | Value | * +-------------------+-----------+ * | status | connected | * | used_memory | 529.25K | * | uptime | 0 days | * | key_count | 20 | * | instantaneous_ops | 9/sec | * | lifetime_hitrate | 53.42% | * | redis_host | 127.0.0.1 | * | redis_port | 6379 | * | redis_auth | | * | redis_database | 0 | * +-------------------+-----------+ * * $ wp redis info --field=used_memory * 529.38K * * $ wp redis info --reset * Success: Redis stats reset. */ public function info($_, $assoc_args) { global $wp_object_cache, $redis_server; if (!defined('WP_REDIS_OBJECT_CACHE') || !WP_REDIS_OBJECT_CACHE) { WP_CLI::error('WP Redis object-cache.php file is missing from the wp-content/ directory.'); } if ($wp_object_cache->is_redis_connected && WP_CLI\Utils\get_flag_value($assoc_args, 'reset')) { // Redis::resetStat() isn't functional, see https://github.com/phpredis/phpredis/issues/928 if ($wp_object_cache->redis->eval("return redis.call('CONFIG','RESETSTAT')")) { WP_CLI::success('Redis stats reset.'); } else { WP_CLI::error("Couldn't reset Redis stats."); } } else { $data = wp_redis_get_info(); if (is_wp_error($data)) { WP_CLI::error($data); } $formatter = new \WP_CLI\Formatter($assoc_args, array_keys($data)); $formatter->display_item($data); } }
/** * Render a collection of items as an ASCII table, JSON, CSV, YAML, list of ids, or count. * * Given a collection of items with a consistent data structure: * * ``` * $items = array( * array( * 'key' => 'foo', * 'value' => 'bar', * ) * ); * ``` * * Render `$items` as an ASCII table: * * ``` * WP_CLI\Utils\format_items( 'table', $items, array( 'key', 'value' ) ); * * # +-----+-------+ * # | key | value | * # +-----+-------+ * # | foo | bar | * # +-----+-------+ * ``` * * Or render `$items` as YAML: * * ``` * WP_CLI\Utils\format_items( 'yaml', $items, array( 'key', 'value' ) ); * * # --- * # - * # key: foo * # value: bar * ``` * * @access public * @category Output * * @param string $format Format to use: 'table', 'json', 'csv', 'yaml', 'ids', 'count' * @param array $items An array of items to output. * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list. * @return null */ function format_items($format, $items, $fields) { $assoc_args = compact('format', 'fields'); $formatter = new \WP_CLI\Formatter($assoc_args); $formatter->display_items($items); }
/** * List all sites in a multisite install. * * ## OPTIONS * * [--network=<id>] * : The network to which the sites belong. * * [--<field>=<value>] * : Filter by one or more fields. * * [--field=<field>] * : Prints the value of a single field for each site. * * [--fields=<fields>] * : Comma-separated list of fields to show. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each site: * * * blog_id * * url * * last_updated * * registered * * These fields are optionally available: * * * site_id * * domain * * path * * public * * archived * * mature * * spam * * deleted * * lang_id * * ## EXAMPLES * * # Output a simple list of site URLs * wp site list --field=url * * @subcommand list */ public function list_($_, $assoc_args) { if (!is_multisite()) { WP_CLI::error('This is not a multisite install.'); } global $wpdb; if (isset($assoc_args['fields'])) { $assoc_args['fields'] = preg_split('/,[ \\t]*/', $assoc_args['fields']); } $defaults = array('format' => 'table', 'fields' => array('blog_id', 'url', 'last_updated', 'registered')); $assoc_args = array_merge($defaults, $assoc_args); $where = array(); $append = ''; $site_cols = array('blog_id', 'url', 'last_updated', 'registered', 'site_id', 'domain', 'path', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id'); foreach ($site_cols as $col) { if (isset($assoc_args[$col])) { $where[$col] = $assoc_args[$col]; } } if (isset($assoc_args['site__in'])) { $where['blog_id'] = explode(',', $assoc_args['site__in']); $append = "ORDER BY FIELD( blog_id, " . implode(',', array_map('intval', $where['blog_id'])) . " )"; } if (isset($assoc_args['network'])) { $where['site_id'] = $assoc_args['network']; } $iterator_args = array('table' => $wpdb->blogs, 'where' => $where, 'append' => $append); $it = new \WP_CLI\Iterators\Table($iterator_args); $it = \WP_CLI\Utils\iterator_map($it, function ($blog) { $blog->url = trailingslashit(get_site_url($blog->blog_id)); return $blog; }); $formatter = new \WP_CLI\Formatter($assoc_args, null, 'site'); $formatter->display_items($it); }
/** * List site options. * * ## OPTIONS * * [--search=<pattern>] * : Use wildcards ( * and ? ) to match option name. * * [--field=<field>] * : Prints the value of a single field. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. * --- * default: table * options: * - table * - json * - csv * - count * - yaml * - total_bytes * --- * * ## AVAILABLE FIELDS * * This field will be displayed by default for each matching option: * * * meta_key * * meta_value * * These fields are optionally available: * * * meta_id * * site_id * * size_bytes * * ## EXAMPLES * * # List all site options begining with "i2f_" * $ wp site option list --search="i2f_*" * +-------------+--------------+ * | meta_key | meta_value | * +-------------+--------------+ * | i2f_version | 0.1.0 | * +-------------+--------------+ * * @subcommand list */ public function list_($args, $assoc_args) { global $wpdb; $pattern = '%'; $fields = array('meta_key', 'meta_value'); $size_query = ",LENGTH(meta_value) AS `size_bytes`"; $autoload_query = ''; if (isset($assoc_args['search'])) { $pattern = self::esc_like($assoc_args['search']); // substitute wildcards $pattern = str_replace('*', '%', $pattern); $pattern = str_replace('?', '_', $pattern); } if (isset($assoc_args['fields'])) { $fields = explode(',', $assoc_args['fields']); } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { $fields = array('size_bytes'); $size_query = ",SUM(LENGTH(meta_value)) AS `size_bytes`"; } $results = $wpdb->get_results($wpdb->prepare("SELECT `meta_id`, `site_id`, `meta_key`,`meta_value`" . $size_query . " FROM `{$wpdb->sitemeta}` WHERE `meta_key` LIKE %s", $pattern)); if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { WP_CLI::line($results[0]->size_bytes); } else { $formatter = new \WP_CLI\Formatter($assoc_args, $fields); $formatter->display_items($results); } }
/** * List locations for the current theme. * * [--format=<format>] * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each location: * * * name * * description * * ## EXAMPLES * * wp menu location list * * @subcommand list */ public function list_($_, $assoc_args) { $locations = get_registered_nav_menus(); $location_objs = array(); foreach ($locations as $location => $description) { $location_obj = new \stdClass(); $location_obj->location = $location; $location_obj->description = $description; $location_objs[] = $location_obj; } $formatter = new \WP_CLI\Formatter($assoc_args, array('location', 'description')); $formatter->display_items($location_objs); }
/** * List options and their values. * * ## OPTIONS * * [--search=<pattern>] * : Use wildcards ( * and ? ) to match option name. * * [--exclude=<pattern>] * : Pattern to exclude. Use wildcards ( * and ? ) to match option name. * * [--autoload=<value>] * : Match only autoload options when value is on, and only not-autoload option when off. * * [--transients] * : List only transients. Use `--no-transients` to ignore all transients. * * [--field=<field>] * : Prints the value of a single field. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. * --- * default: table * options: * - table * - json * - csv * - count * - yaml * - total_bytes * --- * * ## AVAILABLE FIELDS * * This field will be displayed by default for each matching option: * * * option_name * * option_value * * These fields are optionally available: * * * autoload * * size_bytes * * ## EXAMPLES * * # Get the total size of all autoload options. * $ wp option list --autoload=on --format=total_bytes * 33198 * * # Find biggest transients. * $ wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail * option_name size_bytes * _site_transient_timeout_theme_roots 10 * _site_transient_theme_roots 76 * _site_transient_update_themes 181 * _site_transient_update_core 808 * _site_transient_update_plugins 6645 * * # List all options begining with "i2f_". * $ wp option list --search="i2f_*" * +-------------+--------------+ * | option_name | option_value | * +-------------+--------------+ * | i2f_version | 0.1.0 | * +-------------+--------------+ * * # Delete all options begining with "theme_mods_". * $ wp option list --search="theme_mods_*" --field=option_name | xargs -I % wp option delete % * Success: Deleted 'theme_mods_twentysixteen' option. * Success: Deleted 'theme_mods_twentyfifteen' option. * Success: Deleted 'theme_mods_twentyfourteen' option. * * @subcommand list */ public function list_($args, $assoc_args) { global $wpdb; $pattern = '%'; $exclude = ''; $fields = array('option_name', 'option_value'); $size_query = ",LENGTH(option_value) AS `size_bytes`"; $autoload_query = ''; if (isset($assoc_args['search'])) { $pattern = self::esc_like($assoc_args['search']); // substitute wildcards $pattern = str_replace('*', '%', $pattern); $pattern = str_replace('?', '_', $pattern); } if (isset($assoc_args['exclude'])) { $exclude = self::esc_like($assoc_args['exclude']); $exclude = str_replace('*', '%', $exclude); $exclude = str_replace('?', '_', $exclude); } if (isset($assoc_args['fields'])) { $fields = explode(',', $assoc_args['fields']); } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { $fields = array('size_bytes'); $size_query = ",SUM(LENGTH(option_value)) AS `size_bytes`"; } if (isset($assoc_args['autoload'])) { if ('on' === $assoc_args['autoload']) { $autoload_query = " AND autoload='yes'"; } elseif ('off' === $assoc_args['autoload']) { $autoload_query = " AND autoload='no'"; } else { WP_CLI::error("Value of '--autoload' should be on or off."); } } $transients_query = ''; if (true === Utils\get_flag_value($assoc_args, 'transients', null)) { $transients_query = " AND option_name LIKE '\\_transient\\_%'\n\t\t\tOR option_name LIKE '\\_site\\_transient\\_%'"; } else { if (false === Utils\get_flag_value($assoc_args, 'transients', null)) { $transients_query = " AND option_name NOT LIKE '\\_transient\\_%'\n\t\t\tAND option_name NOT LIKE '\\_site\\_transient\\_%'"; } } $where = ''; if ($pattern) { $where .= $wpdb->prepare("WHERE `option_name` LIKE %s", $pattern); } if ($exclude) { $where .= $wpdb->prepare(" AND `option_name` NOT LIKE %s", $exclude); } $where .= $autoload_query . $transients_query; $results = $wpdb->get_results("SELECT `option_name`,`option_value`,`autoload`" . $size_query . " FROM `{$wpdb->options}` {$where}"); if (\WP_CLI\Utils\get_flag_value($assoc_args, 'format') === 'total_bytes') { WP_CLI::line($results[0]->size_bytes); } else { $formatter = new \WP_CLI\Formatter($assoc_args, $fields); $formatter->display_items($results); } }
/** * List registered states. * * @subcommand list-states */ public function list_states($args, $assoc_args) { $states = Dictator::get_states(); $items = array(); foreach ($states as $name => $attributes) { $state_obj = new $attributes['class'](); $regions = implode(',', array_keys($state_obj->get_regions())); $items[] = (object) array('state' => $name, 'regions' => $regions); } $formatter = new \WP_CLI\Formatter($assoc_args, array('state', 'regions')); $formatter->display_items($items); }
/** * Get theme mod(s). * * ## OPTIONS * * [<mod>...] * : One or more mods to get. * * [--all] * : List all theme mods * * [--format=<format>] * : Accepted values: table, json. Default: table * * ## EXAMPLES * * wp theme mod get --all * wp theme mod get background_color --format=json * wp theme mod get background_color header_textcolor */ public function get($args = array(), $assoc_args = array()) { if (!isset($assoc_args['all']) && empty($args)) { WP_CLI::error("You must specify at least one mod or use --all."); } if (isset($assoc_args['all']) && $assoc_args['all']) { $args = array(); } $list = array(); $mods = get_theme_mods(); if (!is_array($mods)) { // if no mods are set (perhaps new theme), make sure foreach still works $mods = array(); } foreach ($mods as $k => $v) { // if mods were given, skip the others if (!empty($args) && !in_array($k, $args)) { continue; } if (is_array($v)) { $list[] = array('key' => $k, 'value' => '=>'); foreach ($v as $_k => $_v) { $list[] = array('key' => " {$_k}", 'value' => $_v); } } else { $list[] = array('key' => $k, 'value' => $v); } } // For unset mods, show blank value foreach ($args as $mod) { if (!isset($mods[$mod])) { $list[] = array('key' => $mod, 'value' => ''); } } $formatter = new \WP_CLI\Formatter($assoc_args, array('key', 'value'), 'thememods'); $formatter->display_items($list); }
/** * View theme on all sites * * ## OPTIONS * * [<theme>...] * : One or more themes, by slug, to look at * * ## EXAMPLES * * wp ms themes * wp ms themes twentytwelve * */ function themes($args, $assoc_args) { if (!is_multisite()) { WP_CLI::error('Must be multisite.'); } global $wpdb; $allblogs = $wpdb->get_results($wpdb->prepare("SELECT blog_id, domain, path FROM {$wpdb->blogs} WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid), ARRAY_A); $blog_list = wp_list_pluck($allblogs, 'blog_id', 'blog_id'); $find = array(); if (isset($args[0])) { $this->fetcher = new \WP_CLI\Fetchers\Theme(); $find = $this->fetcher->get_many($args); foreach ($find as $k => $v) { $find[$k] = $v['Name']; } $find = array_flip($find); } $allthemes = wp_get_themes(); foreach ($allthemes as $k => $v) { $allthemes[$k] = $v['Name']; } foreach ($allblogs as $blog) { $blog_id = $blog['blog_id']; $keys = array('id' => '', 'blog_name' => '', 'theme' => ''); $blog_list[$blog_id] = $keys; $blog_list[$blog_id]['id'] = $blog_id; switch_to_blog($blog_id); $blog_list[$blog_id]['blog_name'] = get_bloginfo('name'); $blog_tables = $wpdb->tables('blog'); $stylesheet = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM {$blog_tables['options']} WHERE option_name = %s", 'stylesheet')); $theme = wp_get_theme($stylesheet); $blog_list[$blog_id]['theme'] = $theme['Name']; if (!empty($find) && !isset($find[$theme['Name']])) { unset($blog_list[$blog_id]); } restore_current_blog(); } ksort($blog_list); $formatter = new \WP_CLI\Formatter($assoc_args, array_keys($keys), 'stash'); $formatter->display_items($blog_list); }
/** * List all user's capabilities. * * ## OPTIONS * * <user> * : User ID, user email, or login. * * [--format=<format>] * : Render output in a particular format. * --- * default: list * options: * - list * - table * - csv * - json * - count * - yaml * --- * * ## EXAMPLES * * $ wp user list-caps 21 * edit_product * create_premium_item * * @subcommand list-caps */ public function list_caps($args, $assoc_args) { $user = $this->fetcher->get_check($args[0]); if ($user) { $user->get_role_caps(); $user_caps_list = $user->allcaps; $active_user_cap_list = array(); foreach ($user_caps_list as $cap => $active) { if ($active) { $active_user_cap_list[] = $cap; } } if ('list' === $assoc_args['format']) { foreach ($active_user_cap_list as $cap) { WP_CLI::line($cap); } } else { $output_caps = array(); foreach ($active_user_cap_list as $cap) { $output_cap = new stdClass(); $output_cap->name = $cap; $output_caps[] = $output_cap; } $formatter = new \WP_CLI\Formatter($assoc_args, $this->cap_fields); $formatter->display_items($output_caps); } } }
/** * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. * * ## OPTIONS * * [--patch] * : Compare only the first two parts of the version number. * * [--minor] * : Compare only the first part of the version number. * * [--field=<field>] * : Prints the value of a single field for each update. * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * * @subcommand check-update */ function check_update($_, $assoc_args) { $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases'; $options = array('timeout' => 30); $headers = array('Accept' => 'application/json'); $response = Utils\http_request('GET', $url, $headers, $options); if (!$response->success || 200 !== $response->status_code) { WP_CLI::error("Failed to get latest version."); } $release_data = json_decode($response->body); $current_parts = explode('.', WP_CLI_VERSION); $updates = array(); foreach ($release_data as $release) { $release_version = $release->tag_name; // get rid of leading "v" if ('v' === substr($release_version, 0, 1)) { $release_version = ltrim($release_version, 'v'); } // don't list earlier releases if (version_compare($release_version, WP_CLI_VERSION, '<=')) { continue; } $release_parts = explode('.', $release_version); $update_type = 'minor'; if ($release_parts[0] === $current_parts[0] && $release_parts[1] === $current_parts[1]) { $update_type = 'patch'; } if (!(isset($assoc_args['patch']) && 'patch' !== $update_type) && !(isset($assoc_args['minor']) && 'minor' !== $update_type) && !$this->same_minor_release($release_parts, $updates)) { $updates[] = array('version' => $release_version, 'update_type' => $update_type, 'package_url' => $release->assets[0]->browser_download_url); } } if ($updates) { $formatter = new \WP_CLI\Formatter($assoc_args, array('version', 'update_type', 'package_url')); $formatter->display_items($updates); } else { if (empty($assoc_args['format']) || 'table' == $assoc_args['format']) { WP_CLI::success("WP-CLI is at the latest version."); } } }