/** * Import images from Unsplash into your Media Library. * * ## OPTIONS * * [--count=<number>] * : How many media items to generate. Default: 10 * * [--media_author=<login>] * : The author of the generated media. Default: none * * [--media_date=<yyyy-mm-dd|random>] * : The date of the generated media. Default: current date * * [--media_dimensions=<dimensions>] * : The dimensions of the generated media. Default: none * * ## EXAMPLES * * wp unsplash --count=10 * wp unsplash --media_date=random * wp unsplash --media_dimensions=1080x720 */ public function __invoke($args, $assoc_args = array()) { $defaults = array('count' => 10, 'media_author' => false, 'media_date' => current_time('mysql'), 'media_dimensions' => false); extract(array_merge($defaults, $assoc_args), EXTR_SKIP); if ($media_author) { $user_fetcher = new \WP_CLI\Fetchers\User(); $media_author = $user_fetcher->get_check($media_author)->ID; } $url = 'https://source.unsplash.com/random/'; if ($media_dimensions) { $url .= $media_dimensions; } $notify = \WP_CLI\Utils\make_progress_bar('Generating media', $count); for ($i = 0; $i < $count; $i++) { $tmp_file = download_url($url); if (!is_wp_error($tmp_file)) { $this->_process_downloaded_image($tmp_file, $media_author, $media_date); } else { WP_CLI::warning('Could not download image from Unsplash API.'); } if (file_exists($tmp_file)) { unlink($tmp_file); } $notify->tick(); } $notify->finish(); }
/** * Generate customers. * * ## Options * * [--count=<count>] * : How many customers to generate. Default: 100 * * [--billing] * : Include billing addresses. * * @param $args * @param $assoc_args * * @subcommand generate-customers */ public function generate_customers($args, $assoc_args) { $count = \WP_CLI\Utils\get_flag_value($assoc_args, 'count', 100); $notify = \WP_CLI\Utils\make_progress_bar("Generating customers", $count); for ($i = 0; $i < $count; $i++) { $this->generate_customer($assoc_args); $notify->tick(); } $notify->finish(); }
private function progress_bar($param, $action = 'Importing') { if ($param && is_numeric($param)) { $this->progress_bar = \WP_CLI\Utils\make_progress_bar("{$action} {$param} records", $param); } elseif ($this->progress_bar && 'tick' == $param) { $this->progress_bar->tick(); } elseif ($this->progress_bar && 'finish' == $param) { $this->progress_bar->finish(); } return $this->progress_bar; }
public function generate_completions() { $completions = array(); $capabilities = $this->get_capabilities(); $progress = \WP_CLI\Utils\make_progress_bar("Generating {$this->name} completions:", count($capabilities)); foreach ($capabilities as $capability) { $completions[] = array('trigger' => "{$capability}\tWP Capability", 'contents' => $capability); ++$this->count; $this->update_messages(); $progress->tick(); } $progress->finish(); return $completions; }
/** * Migrates records from the legacy custom tables into custom post type * * ## OPTIONS * * ## EXAMPLES * * wp rest-api-log migrate * */ function migrate() { WP_CLI::Line("Getting log entries that need to be migrated..."); $db = new WP_REST_API_Log_DB(); $ids = $db->get_log_ids_to_migrate(); $count = count($ids); if (0 === $count) { WP_CLI::Line("There are no more log entries that need to be migrated."); return; } $progress_bar = WP_CLI\Utils\make_progress_bar("Migrating {$count} entries:", $count, 1); $progress_bar->display(); foreach ($ids as $id) { $db->migrate_db_record($id); $progress_bar->tick(); } $progress_bar->finish(); WP_CLI::Success("Log entries migrated"); }
/** * Generate renewal records. * * ## Options * * <rate> * : Renewal rate as a percentage. Ex: 50 or 35 * * [--product=<product>] * : Only generate renewals for a certain product. * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { list($rate) = $args; if ($rate < 1 || $rate > 100) { WP_CLI::error("Usage: 1 < <rate> <= 100"); } $query_args = array('status' => \ITELIC\Key::EXPIRED); if ($p = \WP_CLI\Utils\get_flag_value($assoc_args, 'product')) { $query_args['product'] = $p; } $keys = itelic_get_keys($query_args); $notify = \WP_CLI\Utils\make_progress_bar('Generating renewals.', count($keys)); foreach ($keys as $key) { if (rand(0, 100) <= $rate) { $min = $key->get_expires(); $min->sub(new DateInterval('P15D')); $max = $key->get_expires(); $max->add(new DateInterval('P30D')); $txn = itelic_create_renewal_transaction(array('key' => $key->get_key(), 'date' => $this->faker->dateTimeBetween($min, $max)->format('Y-m-d H:i:s'))); if (is_wp_error($txn)) { WP_CLI::error($txn); } $key->renew($txn); } $notify->tick(); } $notify->finish(); }
/** * Delete all events of the same action */ private function delete_event_by_action($args, $assoc_args) { $action = $assoc_args['action']; // Validate entry if (empty($action)) { \WP_CLI::error(__('Invalid action', 'automattic-cron-control')); } // Warning about Internal Events if (\Automattic\WP\Cron_Control\is_internal_event($action)) { \WP_CLI::warning(__('This is an event created by the Cron Control plugin. It will recreated automatically.', 'automattic-cron-control')); } // Set defaults needed to gather all events $assoc_args['page'] = 1; $assoc_args['limit'] = 50; // Gather events \WP_CLI::line(__('Gathering events...', 'automattic-cron-control')); $events_to_delete = array(); $events = $this->get_events($args, $assoc_args); \WP_CLI::line(sprintf(_n('Found one event to check', 'Found %s events to check', $events['total_items'], 'automattic-cron-control'), number_format_i18n($events['total_items']))); $search_progress = \WP_CLI\Utils\make_progress_bar(sprintf(__('Searching events for those with the action `%s`', 'automattic-cron-control'), $action), $events['total_items']); // Loop and pull out events to be deleted do { if (!is_array($events) || empty($events['items'])) { break; } // Check events for those that should be deleted foreach ($events['items'] as $single_event) { $event_details = $this->get_event_details_from_post_title($single_event->post_title); if ($event_details['action'] === $action) { $events_to_delete[] = array_merge($event_details, array('ID' => (int) $single_event->ID, 'post_date_gmt' => $single_event->post_date_gmt, 'post_modified_gmt' => $single_event->post_modified_gmt)); } $search_progress->tick(); } // Proceed to next batch $assoc_args['page']++; if ($assoc_args['page'] > $events['total_pages']) { break; } $events = $this->get_events($args, $assoc_args); } while ($events['page'] <= $events['total_pages']); $search_progress->finish(); \WP_CLI::line(''); // Nothing more to do if (empty($events_to_delete)) { \WP_CLI::error(sprintf(__('No events with action `%s` found', 'automattic-cron-control'), $action)); } // List the items to remove $total_to_delete = count($events_to_delete); \WP_CLI::line(sprintf(_n('Found one event with action `%2$s`:', 'Found %1$s events with action `%2$s`:', $total_to_delete, 'automattic-cron-control'), number_format_i18n($total_to_delete), $action)); if ($total_to_delete <= $assoc_args['limit']) { \WP_CLI\Utils\format_items('table', $events_to_delete, array('ID', 'post_date_gmt', 'post_modified_gmt', 'timestamp', 'instance')); } else { \WP_CLI::warning(sprintf(__('Events are not displayed as there are more than %s to remove', 'automattic-cron-control'), number_format_i18n($assoc_args['limit']))); } \WP_CLI::line(''); \WP_CLI::confirm(_n('Are you sure you want to delete this event?', 'Are you sure you want to delete these events?', $total_to_delete, 'automattic-cron-control')); // Remove the items $delete_progress = \WP_CLI\Utils\make_progress_bar(__('Deleting events', 'automattic-cron-control'), $total_to_delete); $events_deleted = array(); $events_deleted_count = $events_failed_delete = 0; foreach ($events_to_delete as $event_to_delete) { $deleted = wp_delete_post($event_to_delete['ID'], true); $events_deleted[] = array('ID' => $event_to_delete['ID'], 'deleted' => false === $deleted ? 'no' : 'yes'); if ($deleted) { $events_deleted_count++; } else { $events_failed_delete++; } $delete_progress->tick(); } $delete_progress->finish(); // When deletes succeed, sync internal caches if ($events_deleted_count > 0) { \Automattic\WP\Cron_Control\_flush_internal_caches(); } // List the removed items \WP_CLI::line("\n" . __('RESULTS:', 'automattic-cron-control')); if (1 === $total_to_delete && 1 === $events_deleted_count) { \WP_CLI::success(sprintf(__('Deleted one event: %d', 'automattic-cron-control'), $events_deleted[0]['ID'])); } else { if ($events_deleted_count === $total_to_delete) { \WP_CLI::success(sprintf(__('Deleted %s events', 'automattic-cron-control'), number_format_i18n($events_deleted_count))); } else { \WP_CLI::warning(sprintf(__('Expected to delete %1$s events, but could only delete %2$s events. It\'s likely that some events were executed while this command ran.', 'automattic-cron-control'), number_format_i18n($total_to_delete), number_format_i18n($events_deleted_count))); } // Limit just to failed deletes when many events are removed if (count($events_deleted) > $assoc_args['limit']) { $events_deleted_unfiltered = $events_deleted; $events_deleted = array_filter($events_deleted, function ($event) { if ('no' === $event['deleted']) { return $event; } else { return false; } }); if (count($events_deleted) > 0) { \WP_CLI::line("\n" . __('Events that couldn\'t be deleted:', 'automattic-cron-control')); } } else { \WP_CLI::line("\n" . __('Events deleted:', 'automattic-cron-control')); } // Don't display a table if there's nothing to display if (count($events_deleted) > 0) { \WP_CLI\Utils\format_items('table', $events_deleted, array('ID', 'deleted')); } } return; }
/** * Generate license keys. * * ## Options * * [--count=<count>] * : Number of keys to generate. Default 500. Max 750. * * [--product=<product>] * : Only generate keys for a certain product. * * [--activations] * : Generate activations for license keys. * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { if ($product = \WP_CLI\Utils\get_flag_value($assoc_args, 'product')) { $product = itelic_get_product($product); if (!$product) { WP_CLI::error("Invalid product."); } $products = array($product->ID); } else { $products = wp_list_pluck(itelic_get_products_with_licensing_enabled(), 'ID'); } $count = \WP_CLI\Utils\get_flag_value($assoc_args, 'count', 500); $notify = \WP_CLI\Utils\make_progress_bar("Generating keys", $count); for ($i = 0; $i < $count; $i++) { $product = $this->get_product($products); $customer = $this->get_random_customer(); $min_date = max(strtotime($product->post_date), strtotime($customer->wp_user->user_registered)); $date = $this->faker->dateTimeBetween("@{$min_date}"); $key_args = array('product' => $product->ID, 'customer' => $customer->id, 'date' => $date->format('Y-m-d H:i:s'), 'status' => $this->get_status(), 'paid' => $product->get_feature('base-price')); $key = itelic_create_key($key_args); if (is_wp_error($key)) { WP_CLI::error($key); } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'activations')) { $this->create_activations_for_key($key); } if ($key->get_status() == \ITELIC\Key::EXPIRED) { $key->expire($key->get_expires()); } $notify->tick(); } $notify->finish(); }
/** * Cache posts in batches. * * ## OPTIONS * * <number> * : How many posts to cache Default none. Choose a number or use 'all'. * * [--batch=<number>] * : How many posts to cache in each batch. Default: 50 (-1 to not cache in batches) * * [--sleep=<number>] * : How many seconds of sleep after a batch. Default: 6 (set to 0 for no sleep) * * [--taxonomies=<taxonomies>] * : Comma separated list of taxonomies. Default: all (all registered taxonomies) * * [--post_types=<post-types>] * : post_types parameter. Comma separated list of post types. Default: post * * [--posts_per_page=<posts-per-page>] * : posts_per_page parameter. Default: 5 * * [--order=<order>] * : order parameter. Default DESC (DESC, ASC, or RAND) * * [--limit_posts=<limit-posts>] * : limit_posts parameter. Default: -1 (don't limit posts) * * [--limit_year=<limit-year>] * : limit_year parameter. Default: 0 (bool) * * [--limit_month=<limit-month>] * : limit_month parameter. Default: 0 (bool) * * [--orderby=<orderby>] * : orderby parameter. Default: post_date (post_date or post_modified) * * [--exclude_terms=<exclude-terms>] * : exclude_terms parameter. Comma separated list of term IDs. Default none * * [--include_terms=<include-terms>] * : include_terms parameter. Comma separated list of term IDs. Default none * * [--exclude_posts=<exclude-posts>] * : exclude_posts parameter. Comma separated list of post IDs. Default none * * [--post_thumbnail=<post-thumbnail>] * : post_thumbnail parameter. Default: 0 (bool) * * [--related=<related>] * : related parameter. Default: 1 (bool) * * ## EXAMPLES * * wp rpbt-cache cache 1000 --posts_per_page=9 */ public function cache($args, $assoc_args) { list($count) = $args; $plugin = km_rpbt_plugin(); $defaults = km_rpbt_get_default_args(); if (!$plugin) { WP_CLI::error('Error: Could not find plugin instance'); } $args = wp_parse_args($assoc_args, $defaults); if (!isset($args['taxonomies'])) { $args['taxonomies'] = $plugin->all_tax; } $post_types = explode(',', $args['post_types']); $args = km_rpbt_sanitize_args($args); $taxonomies = $args['taxonomies']; if ($post_types != $args['post_types']) { WP_CLI::error(sprintf("Error: invalid post type in post_types: %s.", implode(', ', $post_types))); } $post_type_count = km_rpbtc_get_post_types_count($args['post_types']); if (!$post_type_count) { WP_CLI::error(sprintf("Error: No posts found for post types: %s.", implode(', ', $args['post_types']))); } $count = 'all' === $count ? $post_type_count : absint($count); if (!$count) { WP_CLI::error("Error: please provide a valid number or 'all'"); } $count = $post_type_count >= $count ? $count : $post_type_count; $notify = \WP_CLI\Utils\make_progress_bar('Caching related posts', $count); $batch = 50; // default batch $sleep = isset($args['sleep']) ? absint($args['sleep']) : 2; if (isset($args['batch'])) { if (-1 === (int) $args['batch']) { $batch = $count; $sleep = 0; } else { $batch = absint($args['batch']); $batch = $batch ? $batch : 50; } } $batch = $batch > $count ? $count : $batch; //unset( $args['taxonomies'], $args['batch'], $args['sleep'] ); for ($i = 0; $i < $count; $i += $batch) { $_args = array('posts_per_page' => $batch, 'post_types' => $args['post_types'], 'offset' => $i, 'fields' => 'ids'); $post_ids = get_posts($_args); if (!empty($post_ids)) { // Cache related posts. km_rpbtc_cache_related_posts($args, $batch, $post_ids, $notify, $sleep); } } $notify->finish(); WP_CLI::success(sprintf("%s posts cached.", $count)); }
/** * Generate update records. * * ## Options * * <product> * : Product ID to generate update records for. * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { list($product) = $args; $product = itelic_get_product($product); if (!$product) { WP_CLI::error("Invalid product ID"); } $releases = itelic_get_releases(array('product' => $product->ID, 'order' => array('start_date' => 'ASC'))); $notify = \WP_CLI\Utils\make_progress_bar(sprintf("Generating Updates: %d", $product->ID), count($releases)); foreach ($releases as $release) { switch ($release->get_type()) { case \ITELIC\Release::TYPE_MAJOR: $percent_updated = 75; break; case \ITELIC\Release::TYPE_MINOR: $percent_updated = 90; break; case \ITELIC\Release::TYPE_SECURITY: $percent_updated = 95; break; case \ITELIC\Release::TYPE_PRERELEASE: $percent_updated = 95; break; default: throw new InvalidArgumentException("Invalid release type."); } $total_activations = new \ITELIC\Query\Activations(array('activation' => array('before' => $release->get_start_date()->format('Y-m-d H:i:s')), 'product' => $product->ID, 'return_value' => 'count')); $total_activations = $total_activations->get_results(); $activations = itelic_get_activations(array('activation' => array('before' => $release->get_start_date()->format('Y-m-d H:i:s')), 'product' => $product->ID, 'order' => 'rand', 'items_per_page' => $total_activations * ($percent_updated / 100))); foreach ($activations as $activation) { if ($activation->get_deactivation() && $activation->get_deactivation() > $release->get_start_date()) { continue; } if ($release->get_type() == ITELIC\Release::TYPE_MAJOR) { $days = rand(0, 10); } else { $days = rand(0, 4); } $upgade_date = $release->get_start_date()->add(new DateInterval("P{$days}D")); \ITELIC\Update::create($activation, $release, $upgade_date); } if ($release->get_status() == \ITELIC\Release::STATUS_ARCHIVED) { $release->set_status(\ITELIC\Release::STATUS_ACTIVE); $release->archive(); } $notify->tick(); } $notify->finish(); }
/** * Generate releases. * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { $products = itelic_get_products_with_licensing_enabled(); $notify = \WP_CLI\Utils\make_progress_bar('Generating Releases', count($products)); $now = new DateTime(); foreach ($products as $product) { $major = get_post_meta($product->ID, '_itelic_first_release', true); $major = itelic_get_release($major); $minor_releases = rand(3, 9); $last = $major; while ($last->get_start_date() < $now) { for ($i = 0; $i < $minor_releases; $i++) { // this exponentially spaces out minor releases $days = rand($i ^ 2, $i + 1 ^ 2); $start = $last->get_start_date()->add(new DateInterval("P{$days}D")); // we don't want to create any releases in the future if ($start > $now) { break 2; } $last = $this->generate_minor_release($last); $last->activate($start); } // between 3 and 7 weeks after a minor release to a major release $days_before_major = rand(3 * 7, 7 * 7); $start = $last->get_start_date()->add(new DateInterval("P{$days_before_major}D")); if ($start > $now) { break; } $last = $this->generate_major_release($last); $last->activate($start); } $notify->tick(); } $notify->finish(); }
/** * Generate users. * * ## OPTIONS * * [--count=<number>] * : How many users to generate. Default: 100 * * [--role=<role>] * : The role of the generated users. Default: default role from WP */ public function generate($args, $assoc_args) { global $blog_id; $defaults = array('count' => 100, 'role' => get_option('default_role')); $assoc_args = array_merge($defaults, $assoc_args); if (!self::validate_role($assoc_args['role'])) { WP_CLI::error("Invalid role: {$role}"); } $user_count = count_users(); $total = $user_count['total_users']; $limit = $assoc_args['count'] + $total; $notify = \WP_CLI\Utils\make_progress_bar('Generating users', $assoc_args['count']); for ($i = $total; $i < $limit; $i++) { $login = sprintf('user_%d_%d', $blog_id, $i); $name = "User {$i}"; $user_id = wp_insert_user(array('user_login' => $login, 'user_pass' => $login, 'nickname' => $name, 'display_name' => $name, 'role' => $role)); if (false === $role) { delete_user_option($user_id, 'capabilities'); delete_user_option($user_id, 'user_level'); } $notify->tick(); } $notify->finish(); }
/** * Generate some terms. * * ## OPTIONS * * <taxonomy> * : The taxonomy for the generated terms. * * [--count=<number>] * : How many terms to generate. Default: 100 * * [--max_depth=<number>] * : Generate child terms down to a certain depth. Default: 1 * * ## EXAMPLES * * wp term generate --count=10 */ public function generate($args, $assoc_args) { global $wpdb; list($taxonomy) = $args; $defaults = array('count' => 100, 'max_depth' => 1); extract(array_merge($defaults, $assoc_args), EXTR_SKIP); if (!taxonomy_exists($taxonomy)) { WP_CLI::error(sprintf("'%s' is not a registered taxonomy.", $taxonomy)); } $label = get_taxonomy($taxonomy)->labels->singular_name; $slug = sanitize_title_with_dashes($label); $hierarchical = get_taxonomy($taxonomy)->hierarchical; $notify = \WP_CLI\Utils\make_progress_bar('Generating terms', $count); $args = array('orderby' => 'id', 'hierarchical' => $hierarchical); $previous_term_id = 0; $current_parent = 0; $current_depth = 1; for ($i = 0; $i < $count; $i++) { if ($hierarchical) { if ($previous_term_id && $this->maybe_make_child() && $current_depth < $max_depth) { $current_parent = $previous_term_id; $current_depth++; } else { if ($this->maybe_reset_depth()) { $current_parent = 0; $current_depth = 1; } } } $args = array('parent' => $current_parent, 'slug' => $slug . "-{$i}"); $term = wp_insert_term("{$label} {$i}", $taxonomy, $args); if (is_wp_error($term)) { WP_CLI::warning($term); } else { $previous_term_id = $term['term_id']; } $notify->tick(); } delete_option($taxonomy . '_children'); $notify->finish(); }
/** * Attach images to posts as post thumbnails or inserted in post content * * @param int $count Number of posts to attach an image to. Default 100 * @param array $args Array of rules for to attach images * * [--post-type=<post-type>] * : Post type to attach images to. Default 'post' * * [--order=<order>] * : Order used to get the posts to attach images to. * Options - DESC, ASC, RAND. Default random order. * * [--size=<size>] * : Image size, either thumbnail, medium, large, random or size set with add_image_size(). * Default none (uses the post thumbnail size set by theme). * * [--include-attached] * : Include already attached images to attach to posts. * * [--insert] * : Insert image in post content instead of adding as a post thumbnail. * * [--linkto=<linkto>] * : Link to file (size) or attachment page if --insert is used * Options - 'file', 'post' or 'none'. Default file. * * [--align=<align>] * : Aligment of image if --insert is used. * Options - 'center', 'left', 'right', 'random'. Default none. * */ function image_gen__attach_images($count, $args = array()) { $defaults = array('post_type' => 'post', 'order' => 'RAND', 'size' => '', 'include-attached' => 0, 'insert' => 0, 'linkto' => 'file', 'align' => ''); $args = wp_parse_args($args, $defaults); if (!post_type_exists($args['post_type'])) { WP_CLI::error(sprintf("'%s' is not a registered post type.", $args['post_type'])); } if (!in_array($args['order'], array('DESC', 'ASC', 'RAND'))) { WP_CLI::error("[--order=<order>] should be one of these values 'DESC', 'ASC' or 'RAND'"); } if (!in_array($args['linkto'], array('file', 'post', 'none'))) { WP_CLI::error("[--linkto=<linkto>] should be one of these values: 'file', 'post' or 'none'"); } if ('' !== $args['size']) { $image_sizes = get_intermediate_image_sizes(); $image_sizes[] = 'random'; if (!in_array($args['size'], $image_sizes)) { WP_CLI::error(sprintf("'%s' is not a correct image size.", $args['size'])); } } $posts = get_posts(array('post_type' => $args['post_type'], 'order' => $args['order'], 'posts_per_page' => absint($count), 'fields' => 'ids')); if (empty($posts)) { WP_CLI::error(sprintf("No posts found for post type %s.", $args['post_type'])); } $notify = \WP_CLI\Utils\make_progress_bar('Attaching images', (int) count($posts)); $attached = 0; foreach ($posts as $post) { $image_id = image_gen__get_random_image_id($args['include-attached']); if (is_null($image_id)) { continue; } if (!$args['insert']) { set_post_thumbnail($post, $image_id); } else { $content = get_post_field('post_content', $post); // Remove multiple lines with only whitespace characters $content = preg_replace('/^\\s*$/', "", $content); // Split at empty lines $content = preg_split('/^\\n+|^[\\t\\s]*\\n+/m', $content, -1, PREG_SPLIT_NO_EMPTY); $size = '' !== $args['size'] ? $args['size'] : 'thumbnail'; if ('random' === $size) { unset($image_sizes['random']); $size = $image_sizes[array_rand($image_sizes)]; } $classes = array('center', 'left', 'right', 'random'); $attr = array('class' => 'attachment-' . $size); $url = ''; if (in_array($args['align'], $classes)) { if ('random' === $args['align']) { unset($classes[3]); $attr['class'] .= ' align' . $classes[array_rand($classes)]; } else { $attr['class'] .= ' align' . $args['align']; } } $image = wp_get_attachment_image($image_id, $size, false, $attr); if ('file' === $args['linkto']) { $url = wp_get_attachment_url($image_id); } if ('post' === $args['linkto']) { $url = get_attachment_link($image_id); } $image = $url ? "<a href='{$url}'>{$image}</a>" : $image; // Insert image into content. $insert = array_rand($content); array_splice($content, $insert, 0, $image); $content = implode("\n\n", $content); wp_update_post(array('ID' => $post, 'post_content' => $content)); } wp_update_post(array('ID' => $image_id, 'post_parent' => $post)); $notify->tick(); ++$attached; } $notify->finish(); if ($attached) { WP_CLI::success(sprintf("%s images attached.", $attached)); } else { WP_CLI::warning("No images attached."); } }
/** * Generate comments. * * ## OPTIONS * * [--count=<number>] * : How many comments to generate. Default: 100 * * [--post_id=<post-id>] * : Assign comments to a specific post. * * [--format=<format>] * : Render output in a particular format. * --- * default: progress * options: * - progress * - ids * --- * * ## EXAMPLES * * # Add meta to every generated comment * $ wp comment generate --format=ids --count=3 | xargs -0 -d ' ' -I % wp comment meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. */ public function generate($args, $assoc_args) { $defaults = array('count' => 100, 'post_id' => null); $assoc_args = array_merge($defaults, $assoc_args); $format = \WP_CLI\Utils\get_flag_value($assoc_args, 'format', 'progress'); $notify = false; if ('progress' === $format) { $notify = \WP_CLI\Utils\make_progress_bar('Generating comments', $assoc_args['count']); } $comment_count = wp_count_comments(); $total = (int) $comment_count->total_comments; $limit = $total + $assoc_args['count']; for ($i = $total; $i < $limit; $i++) { $comment_id = wp_insert_comment(array('comment_content' => "Comment {$i}", 'comment_post_ID' => $assoc_args['post_id'])); if ('progress' === $format) { $notify->tick(); } else { if ('ids' === $format) { if ('ids' === $format) { echo $comment_id; if ($i < $limit - 1) { echo ' '; } } } } } if ('progress' === $format) { $notify->finish(); } }
/** * Generate users. * * ## OPTIONS * * [--count=<number>] * : How many users to generate. Default: 100 * * [--role=<role>] * : The role of the generated users. Default: default role from WP * * [--format=<format>] * : Accepted values: progress, ids. Default: ids. * * ## EXAMPLES * * # Add meta to every generated user * $ wp user generate --format=ids --count=3 | xargs -0 -d ' ' -I % wp user meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. */ public function generate($args, $assoc_args) { global $blog_id; $defaults = array('count' => 100, 'role' => get_option('default_role')); $assoc_args = array_merge($defaults, $assoc_args); $role = $assoc_args['role']; if (!empty($role)) { self::validate_role($role); } $user_count = count_users(); $total = $user_count['total_users']; $limit = $assoc_args['count'] + $total; $format = \WP_CLI\Utils\get_flag_value($assoc_args, 'format', 'progress'); $notify = false; if ('progress' === $format) { $notify = \WP_CLI\Utils\make_progress_bar('Generating users', $assoc_args['count']); } for ($i = $total; $i < $limit; $i++) { $login = sprintf('user_%d_%d', $blog_id, $i); $name = "User {$i}"; $user_id = wp_insert_user(array('user_login' => $login, 'user_pass' => $login, 'nickname' => $name, 'display_name' => $name, 'role' => $role)); if (false === $role) { delete_user_option($user_id, 'capabilities'); delete_user_option($user_id, 'user_level'); } if ('progress' === $format) { $notify->tick(); } else { if ('ids' === $format) { echo $user_id; if ($i < $limit - 1) { echo ' '; } } } } if ('progress' === $format) { $notify->finish(); } }
/** * Assign terms to a post type. * * ## OPTIONS * * <taxonomy> * : The taxonomy to assign to posts. * * [--max-terms=<number>] * : How many terms to assign per post. Default random max terms: 8 * * [--posts=<number>] * : How many posts to assign terms to. Default: 100 * * [--post-type=<post-type>] * : Post type to assign taxonomy terms to. Default: 'post' * * * ## EXAMPLES * * wp term-gen assign post_tag --max-terms=9 --posts=100 --taxonomy=post_tag */ public function assign($args, $assoc_args) { global $wpdb; list($taxonomy) = $args; $defaults = array('max-terms' => 8, 'posts' => 100, 'post-type' => 'post'); $args = wp_parse_args($assoc_args, $defaults); $taxonomy = trim($taxonomy); $post_type = sanitize_key($args['post-type']); $post_count = absint($args['posts']); $term_count = absint($args['max-terms']); if (!taxonomy_exists($taxonomy)) { WP_CLI::error(sprintf("'%s' is not a registered taxonomy.", $taxonomy)); } if (!post_type_exists($post_type)) { WP_CLI::error(sprintf("'%s' is not a registered post type.", $post_type)); } $taxonomy_names = get_object_taxonomies($post_type); if (!in_array($taxonomy, $taxonomy_names)) { WP_CLI::error(sprintf("'%s' is not a registered taxonomy for the post type %s.", $taxonomy, $post_type)); } if (!$post_count) { WP_CLI::error('Post count is not a number'); } if (!$term_count) { WP_CLI::error('Term count is not a number'); } $args = array('posts_per_page' => $post_count, 'post_type' => $post_type, 'orderby' => 'rand', 'fields' => 'ids'); $posts = get_posts($args); if (empty($posts)) { WP_CLI::error(sprintf("No posts found for post type %s.", $post_type)); } $notify = \WP_CLI\Utils\make_progress_bar('Assigning terms', (int) count($posts)); $term_args = array('fields' => 'ids', 'hide_empty' => 0); $assigned_terms = 0; $default_category = get_option('default_category'); $terms_names = array(); $loop_count = 0; foreach ($posts as $post) { $term_args['number'] = mt_rand(0, $term_count); if (!$term_args['number']) { continue; } add_filter('get_terms_orderby', array($this, 'get_random_terms')); $terms = get_terms($taxonomy, $term_args); remove_filter('get_terms_orderby', array($this, 'get_random_terms')); if (is_wp_error($terms) || empty($terms)) { continue; } $terms = array_map('intval', $terms); $append = true; if ('category' === $taxonomy && in_array($default_category, $terms)) { if (mt_rand(1, 100) <= 85) { $key = array_search($default_category, $terms); // $key = 2; unset($terms[$key]); } } if (empty($terms)) { continue; } $assigned_terms += count($terms); wp_set_object_terms($post, $terms, $taxonomy); $notify->tick(); if (0 == $loop_count % 200) { //WP_CLI::success('sleep '); sleep(3); } $loop_count++; } $notify->finish(); if ($assigned_terms) { WP_CLI::success(sprintf("%s terms assigned.", $assigned_terms)); } else { WP_CLI::warning(sprintf("No terms from %s assigned.", $taxonomy)); } }
/** * Generate product categories. * * ## OPTIONS * * [--count=<number>] * : How many categories to generate. Default: 10 * * ## EXAMPLES * * # Generate 10 product categories * wp wpsc-category generate * * # Generate 20 product categories * wp wpsc-category generate --count=20 * */ function generate($args, $assoc_args) { $count = isset($assoc_args['count']) ? (int) $assoc_args['count'] : 10; $notify = \WP_CLI\Utils\make_progress_bar(__('Generating categories', 'wpsc'), $count); for ($i = 1; $i <= $count; $i++) { $name = sprintf(__('Product category %d', 'wpsc'), $i); if (!is_wp_error(wp_insert_term($name, 'wpsc_product_category', array()))) { $notify->tick(); } else { WP_CLI::error(sprintf(__('Failed to create %s', 'wpsc'), $name)); } } $notify->finish(); }
/** * Import the PHPDoc $data into WordPress posts and taxonomies * * @param array $data * @param bool $skip_sleep Optional; defaults to false. If true, the sleep() calls are skipped. * @param bool $import_ignored_functions Optional; defaults to false. If true, functions marked `@ignore` will be imported. * Disabled, not remove to prevent PHP Warning */ public function import(array $data, $skip_sleep = false, $import_ignored_functions = false) { parent::import($data, $skip_sleep); global $wpdb; // Delete orphans posts $post_types = $post_ids = array(); foreach ($this->imported as $post_type => $l) { $post_types[] = "'{$post_type}'"; $post_ids = array_merge($post_ids, array_map('absint', $l)); } $post_types = implode(',', $post_types); $post_ids = implode(',', $post_ids); if ($post_ids = $wpdb->get_col("SELECT DISTINCT ID FROM {$wpdb->posts} WHERE post_type IN ({$post_types}) AND ID NOT IN ({$post_ids})")) { $progress = \WP_CLI\Utils\make_progress_bar('Deleting orphans posts.', count($post_ids)); foreach ($post_ids as $post_id) { wp_delete_post($post_id, true); $progress->tick(); } $progress->finish(); } // Delete empty taxonomies if ($terms = $wpdb->get_results("SELECT tt.term_id, tt.taxonomy FROM {$wpdb->term_taxonomy} AS tt WHERE tt.taxonomy LIKE '%wp-parser-%' AND tt.count = 0")) { $progress = \WP_CLI\Utils\make_progress_bar('Deleting empty taxonomies.', count($terms)); foreach ($terms as $term) { wp_delete_term($term->term_id, $term->taxonomy); $progress->tick(); } $progress->finish(); } }
/** * Generate some terms. * * ## OPTIONS * * <taxonomy> * : The taxonomy for the generated terms. * * [--count=<number>] * : How many terms to generate. Default: 100 * * [--max_depth=<number>] * : Generate child terms down to a certain depth. Default: 1 * * ## EXAMPLES * * wp term generate --count=10 */ public function generate($args, $assoc_args) { global $wpdb; list($taxonomy) = $args; $defaults = array('count' => 100, 'max_depth' => 1); extract(array_merge($defaults, $assoc_args), EXTR_SKIP); if (!taxonomy_exists($taxonomy)) { WP_CLI::error(sprintf("'%s' is not a registered taxonomy.", $taxonomy)); } $label = get_taxonomy($taxonomy)->labels->singular_name; $slug = sanitize_title_with_dashes($label); $hierarchical = get_taxonomy($taxonomy)->hierarchical; $notify = \WP_CLI\Utils\make_progress_bar('Generating terms', $count); $previous_term_id = 0; $current_parent = 0; $current_depth = 1; $max_id = (int) $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} ORDER BY term_taxonomy_id DESC LIMIT 1"); $suspend_cache_invalidation = wp_suspend_cache_invalidation(true); $created = array(); for ($i = $max_id + 1; $i <= $max_id + $count; $i++) { if ($hierarchical) { if ($previous_term_id && $this->maybe_make_child() && $current_depth < $max_depth) { $current_parent = $previous_term_id; $current_depth++; } else { if ($this->maybe_reset_depth()) { $current_parent = 0; $current_depth = 1; } } } $args = array('parent' => $current_parent, 'slug' => $slug . "-{$i}"); $name = "{$label} {$i}"; $term = wp_insert_term($name, $taxonomy, $args); if (is_wp_error($term)) { WP_CLI::warning($term); } else { $created[] = $term['term_id']; $previous_term_id = $term['term_id']; } $notify->tick(); } wp_suspend_cache_invalidation($suspend_cache_invalidation); clean_term_cache($created, $taxonomy); $notify->finish(); }
/** * Purge cache files * * ## OPTIONS * * [--post_id=<post_id>] * : List posts to purge cache files. * * [--permalink=<permalink>] * : List permalinks to purge cache files. Trumps --post_id. * * [--lang=<lang>] * : List langs to purge cache files. Trumps --post_id & --permalink. * * [--blog_id=<blog_id>] * : List blogs to purge cache files. Trumps --post_id & --permalink & lang. * * ## EXAMPLES * * wp rocket clean * wp rocket clean --post_id=2 * wp rocket clean --post_id=2,4,6,8 * wp rocket clean --permalink=http://example.com * wp rocket clean --permalink=http://example.com, http://example.com/category/(.*) * wp rocket clean --lang=fr * wp rocket clean --lang=fr,de,en,it * wp rocket clean --blog_id=2 * wp rocket clean --blog_id=2,4,6,8 * * @subcommand clean */ public function clean($args = array(), $assoc_args = array()) { if (!empty($assoc_args['blog_id'])) { if (!defined('MULTISITE') || !MULTISITE) { WP_CLI::error('This installation doesn\'t multisite support.'); } $blog_ids = explode(',', $assoc_args['blog_id']); $blog_ids = array_map('trim', $blog_ids); $total = 0; $notify = \WP_CLI\Utils\make_progress_bar('Delete cache files', count($blog_ids)); foreach ($blog_ids as $blog_id) { if ($bloginfo = get_blog_details((int) $blog_id, false)) { switch_to_blog($blog_id); rocket_clean_domain(); WP_CLI::line('Cache cleared for "' . esc_url('http://' . $bloginfo->domain . $bloginfo->path) . '".'); restore_current_blog(); $total++; } else { WP_CLI::line('This blog ID "' . $blog_id . '" doesn\'t exist.'); } $notify->tick(); } $notify->finish(); WP_CLI::success('Cache cleared for ' . $total . ' blog(s).'); } else { if (!empty($assoc_args['lang'])) { if (!rocket_has_translation_plugin_active()) { WP_CLI::error('No WPML or qTranslate in this website.'); } $langs = explode(',', $assoc_args['lang']); $langs = array_map('trim', $langs); $total = count($langs); $notify = \WP_CLI\Utils\make_progress_bar('Delete cache files', $total); foreach ($langs as $lang) { rocket_clean_domain_for_selected_lang($lang); $notify->tick(); } $notify->finish(); WP_CLI::success('Cache files cleared for ' . $total . ' lang(s).'); } else { if (!empty($assoc_args['permalink'])) { $permalinks = explode(',', $assoc_args['permalink']); $permalinks = array_map('trim', $permalinks); $total = count($permalinks); $notify = \WP_CLI\Utils\make_progress_bar('Delete cache files', $total); foreach ($permalinks as $permalink) { rocket_clean_files($permalink); WP_CLI::line('Cache cleared for "' . $permalink . '".'); $notify->tick(); } $notify->finish(); WP_CLI::success('Cache files cleared for ' . $total . ' permalink(s).'); } else { if (!empty($assoc_args['post_id'])) { $total = 0; $post_ids = explode(',', $assoc_args['post_id']); $post_ids = array_map('trim', $post_ids); $notify = \WP_CLI\Utils\make_progress_bar('Delete cache files', count($post_ids)); foreach ($post_ids as $post_id) { global $wpdb; $post_exists = $wpdb->get_row("SELECT ID FROM {$wpdb->posts} WHERE id = '" . (int) $post_id . "'"); if ($post_exists) { if (get_post_type($post_id) == 'attachment') { WP_CLI::line('This post ID "' . $post_id . '" is an attachment.'); } else { rocket_clean_post($post_id); WP_CLI::line('Cache cleared for post ID "' . $post_id . '".'); $total++; } } else { WP_CLI::line('This post ID "' . $post_id . '" doesn\'t exist.'); } $notify->tick(); } if ($total) { $notify->finish(); if ($total == 1) { WP_CLI::success('1 post is cleared.'); } else { WP_CLI::success($total . ' posts are cleared.'); } } else { WP_CLI::error('No cache files are cleared.'); } } else { WP_CLI::confirm('Delete all cache files ?'); if (rocket_has_translation_plugin_active()) { rocket_clean_domain_for_all_langs(); } else { rocket_clean_domain(); } WP_CLI::success('All cache files cleared.'); } } } } }
/** * Generate comments. * * ## OPTIONS * * [--count=<number>] * : How many comments to generate. Default: 100 */ public function generate($args, $assoc_args) { $defaults = array('count' => 100); $assoc_args = array_merge($defaults, $assoc_args); $notify = \WP_CLI\Utils\make_progress_bar('Generating comments', $assoc_args['count']); $comment_count = wp_count_comments(); $total = (int) $comment_count->total_comments; $limit = $total + $assoc_args['count']; for ($i = $total; $i < $limit; $i++) { wp_insert_comment(array('comment_content' => "Comment {$i}")); $notify->tick(); } $notify->finish(); }
/** * Generate products. * * ## Options * * [--file=<file>] * : Specify which files to used. By default pulls random zips from DB. * * [--count=<count>] * : How many products to generate. Default: 15 * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { $count = \WP_CLI\Utils\get_flag_value($assoc_args, 'count', 15); if (!\WP_CLI\Utils\get_flag_value($assoc_args, 'file')) { /** * @var \wpdb $wpdb */ global $wpdb; $results = $wpdb->get_results($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment'\n\t\t\t\t AND post_mime_type = 'application/zip' LIMIT %d", $count)); $files = array(); foreach ($results as $result) { $files[] = $result->ID; } } else { if (get_post_type($assoc_args['file']) != 'attachment') { WP_CLI::error("Invalid file post type."); } $files = array($assoc_args['file']); } if (empty($files)) { WP_CLI::error('No files exist.'); } $notify = \WP_CLI\Utils\make_progress_bar('Generating products.', $count); $limits = array('-', '2', '2', '5', '5', '10'); for ($i = 0; $i < $count; $i++) { $title = $this->faker->catchPhrase . ' software'; $price = itelic_purebell(44, 199, 45); $price = floatval(intval($price)); $index = array_rand($files); $file = get_post($files[$index]); try { $file = itelic_rename_file($file, $title . '-1.0.zip'); } catch (InvalidArgumentException $e) { WP_CLI::error($e->getMessage()); } $params = array('description' => $this->faker->realText(), 'limit' => $limits[array_rand($limits)], 'file' => $file->ID); $recurring = array(array('interval' => 'month', 'count' => 1, 'frequency' => 10), array('interval' => 'month', 'count' => 6, 'frequency' => 20), array('interval' => 'none', 'frequency' => 30), array('interval' => 'year', 'count' => 1, 'frequency' => 100)); $rand = rand(0, 100); foreach ($recurring as $option) { if ($rand <= $option['frequency']) { if ($option['interval'] != 'none') { $params['interval'] = $option['interval']; $params['interval-count'] = $option['count']; } break; } } $result = $this->create_product($title, $price, $params); if (is_wp_error($result)) { WP_CLI::error($result); } $notify->tick(); } $notify->finish(); }
/** * Generate some posts. * * ## OPTIONS * * [--count=<number>] * : How many posts to generate. Default: 100 * * [--post_type=<type>] * : The type of the generated posts. Default: 'post' * * [--post_status=<status>] * : The status of the generated posts. Default: 'publish' * * [--post_author=<login>] * : The author of the generated posts. Default: none * * [--post_date=<yyyy-mm-dd>] * : The date of the generated posts. Default: current date * * [--post_content] * : If set, the command reads the post_content from STDIN. * * [--max_depth=<number>] * : For hierarchical post types, generate child posts down to a certain depth. Default: 1 * * ## EXAMPLES * * wp post generate --count=10 --post_type=page --post_date=1999-01-04 * curl http://loripsum.net/api/5 | wp post generate --post_content --count=10 */ public function generate($args, $assoc_args) { global $wpdb; $defaults = array('count' => 100, 'max_depth' => 1, 'post_type' => 'post', 'post_status' => 'publish', 'post_author' => false, 'post_date' => current_time('mysql'), 'post_content' => ''); extract(array_merge($defaults, $assoc_args), EXTR_SKIP); // @codingStandardsIgnoreStart if (!post_type_exists($post_type)) { WP_CLI::error(sprintf("'%s' is not a registered post type.", $post_type)); } if ($post_author) { $user_fetcher = new \WP_CLI\Fetchers\User(); $post_author = $user_fetcher->get_check($post_author)->ID; } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'post_content')) { $post_content = file_get_contents('php://stdin'); } // Get the total number of posts $total = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s", $post_type)); $label = get_post_type_object($post_type)->labels->singular_name; $hierarchical = get_post_type_object($post_type)->hierarchical; $limit = $count + $total; $notify = \WP_CLI\Utils\make_progress_bar('Generating posts', $count); $previous_post_id = 0; $current_depth = 1; $current_parent = 0; for ($i = $total; $i < $limit; $i++) { if ($hierarchical) { if ($this->maybe_make_child() && $current_depth < $max_depth) { $current_parent = $previous_post_id; $current_depth++; } else { if ($this->maybe_reset_depth()) { $current_depth = 1; $current_parent = 0; } } } $args = array('post_type' => $post_type, 'post_title' => "{$label} {$i}", 'post_status' => $post_status, 'post_author' => $post_author, 'post_parent' => $current_parent, 'post_name' => "post-{$i}", 'post_date' => $post_date, 'post_content' => $post_content); $post_id = wp_insert_post($args, true); if (is_wp_error($post_id)) { WP_CLI::warning($post_id); } else { $previous_post_id = $post_id; } $notify->tick(); } $notify->finish(); // @codingStandardsIgnoreEnd }
/** * Generate a number of dummy sessions for testing purposes. * * ## OPTIONS * * <count> * : Number of sessions to create. * * [--expires=<date>] * : Optional expiration time tagged for each session. Will use WordPress' local time. * * ## EXAMPLES * * wp session generate 5000 * wp session generate 5000 --expires="2014-11-09T08:00" * * @synopsis <count> [--expires=<date>] * * @param array $args * @param array $assoc_args */ public function generate($args, $assoc_args) { $count = absint($args[0]); $date = isset($assoc_args['expires']) ? $assoc_args['expires'] : null; $notify = \WP_CLI\Utils\make_progress_bar('Generating sessions', $count); for ($i = 0; $i < $count; $i++) { WP_Session_Utils::create_dummy_session($date); $notify->tick(); } $notify->finish(); }
/** * Deletes all users excepts administrators. * * ## EXAMPLES * * wp usergen purge * * @access public * @param array $args * @param array $assoc_args * @return void */ public function purge($args, $assoc_args) { WP_CLI::line(''); WP_CLI::confirm('Are you sure you want to remove all users? This will NOT delete administrators.'); $roles_to_delete = $this->get_roles(); foreach ($roles_to_delete as $role => $name) { $query_args = array('role' => $role, 'number' => 99999999); $user_query = new WP_User_Query($query_args); $results = $user_query->get_results(); $total = $user_query->get_total(); if (!empty($results)) { WP_CLI::line(''); $notify = \WP_CLI\Utils\make_progress_bar("Deleting {$total} {$name}(s)", $total); for ($i = 0; $i < count($results); $i++) { $notify->tick(); wp_delete_user($results[$i]->data->ID, null); } $notify->finish(); } } WP_CLI::line(''); WP_CLI::success('Done.'); WP_CLI::line(''); }