Example #1
0
 /**
  * Show table
  *
  * @param array $header
  * @param array $body
  */
 protected static function table($header, $body)
 {
     $table = new \cli\Table();
     $table->setHeaders($header);
     $table->setRows($body);
     $table->display();
 }
 /**
  * Lists one-time logins
  *
  * ## EXAMPLES
  *
  *     wp one-time-login list
  *
  * @subcommand list
  */
 function _list($args, $assoc_args)
 {
     // Get all one-time logins
     $otl_posts = get_posts(array('posts_per_page' => -1, 'post_type' => 'onetimelogin', 'order' => ASC));
     // Error if no logins found
     if (empty($otl_posts)) {
         WP_CLI::error(__('No one time logins found.', 'one-time-login'));
     }
     // Set table headers
     $headers = array(__('ID', 'one-time-login'), __('Password', 'one-time-login'), __('User ID', 'one-time-login'), __('Date Generated', 'one-time-login'), __('Status', 'one-time-login'), __('Date Used', 'one-time-login'));
     $data = array();
     // loop through logins and format
     foreach ($otl_posts as $otl) {
         $id = $otl->ID;
         $password = $otl->post_title;
         $user_id = get_post_meta($otl->ID, 'otl_user', true);
         $generated = $otl->post_date;
         $status = '0' === get_post_meta($otl->ID, 'otl_times_used', true) ? __('Available', 'one-time-login') : __('Expired', 'one-time-login');
         $used = get_post_meta($otl->ID, 'otl_datetime_used', true);
         $data[] = array($id, $password, $user_id, $generated, $status, $used);
     }
     // Output table
     $table = new \cli\Table();
     $table->setHeaders($headers);
     $table->setRows($data);
     $table->display();
 }
Example #3
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in all tables and will replace all
  * appearances of the old string with the new one.
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  */
 public function __invoke($args, $assoc_args)
 {
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $dry_run = isset($assoc_args['dry-run']);
     $recurse_objects = isset($assoc_args['recurse-objects']);
     if (isset($assoc_args['skip-columns'])) {
         $skip_columns = explode(',', $assoc_args['skip-columns']);
     } else {
         $skip_columns = array();
     }
     // never mess with hashed passwords
     $skip_columns[] = 'user_pass';
     $tables = self::get_table_list($args, isset($assoc_args['network']));
     foreach ($tables as $table) {
         list($primary_key, $columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (null === $primary_key) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $skip_columns)) {
                 continue;
             }
             $count = self::handle_col($col, $primary_key, $table, $old, $new, $dry_run, $recurse_objects);
             $report[] = array($table, $col, $count);
             $total += $count;
         }
     }
     $table = new \cli\Table();
     $table->setHeaders(array('Table', 'Column', 'Replacements'));
     $table->setRows($report);
     $table->display();
     if (!$dry_run) {
         WP_CLI::success("Made {$total} replacements.");
     }
 }
Example #4
0
<?php

require 'vendor/autoload.php';
echo "Hello World!\n\n";
echo "Payload: ";
print_r(IronWorker\Runtime::getPayload(true));
echo "\nConfig: ";
print_r(IronWorker\Runtime::getConfig(true));
// Add iron.json and uncomment this block to actually use it
/*
$ironmq = new \IronMQ\IronMQ();
$ironmq->postMessage('Some Queue', "Hello world");
$msg = $ironmq->getMessage('Some Queue');
var_dump($msg)
*/
echo "\n\nCLI Table:\n";
$headers = array('Id', 'Name', 'City');
$data = array(array(1, 'Elliott', 'San Francisco'), array(2, 'Washington', 'Bessemer'), array(3, 'Hopkins', 'Altoona'));
$table = new \cli\Table();
$table->setHeaders($headers);
$table->setRows($data);
$table->display();
Example #5
0
 public function execute(array $args, array $options = array())
 {
     # setUserMigration Path
     $this->migrationPath = isset($options['migration_path']) ? $options['migration_path'] : null;
     $list = $this->getDirectoryTree($this->getMigrationPath(), "php");
     # get filename
     $file = isset($options['f']) ? true : false;
     $filter_apply = isset($options['a']) ? $options['a'] : false;
     $filter_new = isset($options['n']) ? $options['n'] : false;
     $filter_from = isset($options['from']) ? $options['from'] : false;
     $filter_to = isset($options['to']) ? $options['to'] : false;
     $filter_from = $filter_from ? strtotime($filter_from) : false;
     $filter_to = $filter_to ? strtotime($filter_to) : false;
     #check tag list
     $filer_tag = isset($options['tag']) ? $options['tag'] : false;
     if (!empty($list)) {
         $headers = array('№', 'id', 'Author', 'Date');
         if ($file) {
             $headers[] = 'File';
         }
         $headers[] = 'Description';
         $headers[] = 'Status';
         $table = new \cli\Table();
         $table->setHeaders($headers);
         $count = 0;
         $applied = 0;
         $new = 0;
         $i = 1;
         $return_array_new = array();
         $return_array_apply = array();
         #filter
         $is_filter = false;
         $this->prepareFilter($list, $filter_from, $filter_to, $filer_tag, $options, $is_filter);
         foreach ($list as $id => $data) {
             $count++;
             $row = $data['file'];
             $name = $data['name'];
             # check in db
             $is_new = !$this->checkInDb($id);
             $class_name = "Migration" . $id;
             include_once "" . $this->getMigrationPath() . $row . "";
             $color = ConsoleKit\Colors::GREEN;
             $status = ConsoleKit\Colors::colorize('apply', Colors::GREEN);
             # check in db
             if ($is_new) {
                 $new++;
                 $color = ConsoleKit\Colors::RED;
                 $status = ConsoleKit\Colors::colorize('new', Colors::RED);
             } else {
                 $applied++;
             }
             $rowArray = array(ConsoleKit\Colors::colorize($i, $color), ConsoleKit\Colors::colorize($id, $color), $data['author'], date("d.m.y G:h", $data['date']));
             if ($file) {
                 $rowArray[] = $row;
             }
             $rowArray[] = $data['description'];
             $rowArray[] = $status;
             if ($is_new) {
                 $return_array_new[] = $rowArray;
             } else {
                 $return_array_apply[] = $rowArray;
             }
             $i++;
         }
         if ($filter_new) {
             $table->setRows($return_array_new);
         } else {
             if ($filter_apply) {
                 $table->setRows($return_array_apply);
             } else {
                 $table->setRows(array_merge($return_array_apply, $return_array_new));
             }
         }
         $displayArray = $table->getDisplayLines();
         if (!empty($displayArray)) {
             $table->display();
         }
         if (!$is_filter) {
             # count info
             $return[] = Colors::colorize('New:', Colors::RED) . " " . $new;
             $return[] = Colors::colorize('Applied:', Colors::GREEN) . " " . $applied;
             $return[] = "Count: " . $count;
         }
         # display
         $this->padding(implode(PHP_EOL, $return));
     } else {
         $this->info('Empty migration');
     }
 }
Example #6
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in a selection of tables
  * and will replace all appearances of the old string with the new one.  The
  * default tables are those registered on the $wpdb object (usually
  * just WordPress core tables).
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to. Wildcards are supported, e.g. wp_\*_options or wp_post\?.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--precise]
  * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings. Defaults to true; pass --no-recurse-objects to disable.
  *
  * [--all-tables-with-prefix]
  * : Enable replacement on any tables that match the table prefix even if not registered on wpdb
  *
  * [--all-tables]
  * : Enable replacement on ALL tables in the database, regardless of the prefix, and even if not registered on $wpdb. Overrides --network and --all-tables-with-prefix.
  *
  * [--verbose]
  * : Prints rows to the console as they're updated.
  *
  * [--regex]
  * : Runs the search using a regular expression. Warning: search-replace will take about 15-20x longer when using --regex.
  *
  * [--export[=<file>]]
  * : Write transformed data as SQL file instead of performing in-place replacements. If <file> is not supplied, will output to STDOUT.
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  *
  *     # Turn your production database into a local database
  *     wp search-replace --url=example.com example.com example.dev wp_\*_options
  *
  *     # Search/replace to a SQL file without transforming the database
  *     wp search-replace foo bar --export=database.sql
  */
 public function __invoke($args, $assoc_args)
 {
     global $wpdb;
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $this->dry_run = \WP_CLI\Utils\get_flag_value($assoc_args, 'dry-run');
     $php_only = \WP_CLI\Utils\get_flag_value($assoc_args, 'precise');
     $this->recurse_objects = \WP_CLI\Utils\get_flag_value($assoc_args, 'recurse-objects', true);
     $this->verbose = \WP_CLI\Utils\get_flag_value($assoc_args, 'verbose');
     $this->regex = \WP_CLI\Utils\get_flag_value($assoc_args, 'regex');
     $this->skip_columns = explode(',', \WP_CLI\Utils\get_flag_value($assoc_args, 'skip-columns'));
     if ($old === $new && !$this->regex) {
         WP_CLI::warning("Replacement value '{$old}' is identical to search value '{$new}'. Skipping operation.");
         exit;
     }
     if (null !== ($export = \WP_CLI\Utils\get_flag_value($assoc_args, 'export'))) {
         if ($this->dry_run) {
             WP_CLI::error('You cannot supply --dry-run and --export at the same time.');
         }
         if (true === $export) {
             $this->export_handle = STDOUT;
             $this->verbose = false;
         } else {
             $this->export_handle = fopen($assoc_args['export'], 'w');
             if (false === $this->export_handle) {
                 WP_CLI::error(sprintf('Unable to open "%s" for writing.', $assoc_args['export']));
             }
         }
         $php_only = true;
     }
     // never mess with hashed passwords
     $this->skip_columns[] = 'user_pass';
     // Get table names based on leftover $args or supplied $assoc_args
     $tables = \WP_CLI\Utils\wp_get_table_names($args, $assoc_args);
     foreach ($tables as $table) {
         if ($this->export_handle) {
             fwrite($this->export_handle, "\nDROP TABLE IF EXISTS `{$table}`;\n");
             $row = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N);
             fwrite($this->export_handle, $row[1] . ";\n");
             list($table_report, $total_rows) = $this->php_export_table($table, $old, $new);
             $report = array_merge($report, $table_report);
             $total += $total_rows;
             // Don't perform replacements on the actual database
             continue;
         }
         list($primary_keys, $columns, $all_columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (empty($primary_keys)) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $this->skip_columns)) {
                 continue;
             }
             if ($this->verbose) {
                 $this->start_time = microtime(true);
                 WP_CLI::log(sprintf('Checking: %s.%s', $table, $col));
             }
             if (!$php_only && !$this->regex) {
                 $serialRow = $wpdb->get_row("SELECT * FROM `{$table}` WHERE `{$col}` REGEXP '^[aiO]:[1-9]' LIMIT 1");
             }
             if ($php_only || $this->regex || NULL !== $serialRow) {
                 $type = 'PHP';
                 $count = $this->php_handle_col($col, $primary_keys, $table, $old, $new);
             } else {
                 $type = 'SQL';
                 $count = $this->sql_handle_col($col, $table, $old, $new);
             }
             $report[] = array($table, $col, $count, $type);
             $total += $count;
         }
     }
     if ($this->export_handle && STDOUT !== $this->export_handle) {
         fclose($this->export_handle);
     }
     // Only informational output after this point
     if (WP_CLI::get_config('quiet') || STDOUT === $this->export_handle) {
         return;
     }
     $table = new \cli\Table();
     $table->setHeaders(array('Table', 'Column', 'Replacements', 'Type'));
     $table->setRows($report);
     $table->display();
     if (!$this->dry_run) {
         if (!empty($assoc_args['export'])) {
             $success_message = "Made {$total} replacements and exported to {$assoc_args['export']}.";
         } else {
             $success_message = "Made {$total} replacements.";
             if ($total && 'Default' !== WP_CLI\Utils\wp_get_cache_type()) {
                 $success_message .= ' Please remember to flush your persistent object cache with `wp cache flush`.';
             }
         }
         WP_CLI::success($success_message);
     }
 }
Example #7
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in all tables and will replace all
  * appearances of the old string with the new one.
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--precise]
  * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings
  *
  * [--all-tables-with-prefix]
  * : Enable replacement on any tables that match the table prefix even if not registered on wpdb
  *
  * [--all-tables]
  * : Enable replacement on ALL tables in the database, regardless of the prefix. Overrides --network and --all-tables-with-prefix.
  *
  * [--verbose]
  * : Prints rows to the console as they're updated.
  *
  * [--regex]
  * : Runs the search using a regular expression. Warning: search-replace will take about 15-20x longer when using --regex.
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  *
  *     # Turn your production database into a local database
  *     wp search-replace --url=example.com example.com example.dev
  */
 public function __invoke($args, $assoc_args)
 {
     global $wpdb;
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $dry_run = \WP_CLI\Utils\get_flag_value($assoc_args, 'dry-run');
     $php_only = \WP_CLI\Utils\get_flag_value($assoc_args, 'precise');
     $recurse_objects = \WP_CLI\Utils\get_flag_value($assoc_args, 'recurse-objects');
     $verbose = \WP_CLI\Utils\get_flag_value($assoc_args, 'verbose');
     $regex = \WP_CLI\Utils\get_flag_value($assoc_args, 'regex');
     $skip_columns = explode(',', \WP_CLI\Utils\get_flag_value($assoc_args, 'skip-columns'));
     // never mess with hashed passwords
     $skip_columns[] = 'user_pass';
     // Determine how to limit the list of tables. Defaults to 'wordpress'
     $table_type = 'wordpress';
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'network')) {
         $table_type = 'network';
     }
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'all-tables-with-prefix')) {
         $table_type = 'all-tables-with-prefix';
     }
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'all-tables')) {
         $table_type = 'all-tables';
     }
     // Get the array of tables to work with. If there is anything left in $args, assume those are table names to use
     $tables = empty($args) ? self::get_table_list($table_type) : $args;
     foreach ($tables as $table) {
         list($primary_keys, $columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (empty($primary_keys)) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $skip_columns)) {
                 continue;
             }
             if (!$php_only) {
                 $serialRow = $wpdb->get_row("SELECT * FROM `{$table}` WHERE `{$col}` REGEXP '^[aiO]:[1-9]' LIMIT 1");
             }
             if ($php_only || $regex || NULL !== $serialRow) {
                 $type = 'PHP';
                 $count = self::php_handle_col($col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex);
             } else {
                 $type = 'SQL';
                 $count = self::sql_handle_col($col, $table, $old, $new, $dry_run, $verbose);
             }
             $report[] = array($table, $col, $count, $type);
             $total += $count;
         }
     }
     if (!WP_CLI::get_config('quiet')) {
         $table = new \cli\Table();
         $table->setHeaders(array('Table', 'Column', 'Replacements', 'Type'));
         $table->setRows($report);
         $table->display();
         if (!$dry_run) {
             WP_CLI::success("Made {$total} replacements.");
         }
     }
 }
Example #8
0
function print_cli_table($table_rows, $table_header = array(), $descr = NULL)
{
    if (!is_array($table_rows)) {
        print_error("print_cli_table() argument {$table_rows} should be an array. Please report this error to developers.");
        return;
    }
    if (OBS_QUIET) {
        return;
    }
    if (!cli_is_piped() || OBS_DEBUG) {
        $count_rows = count($table_rows);
        if ($count_rows == 0) {
            return;
        }
        if (strlen($descr)) {
            print_cli_data($descr, '', 3);
        }
        $table = new \cli\Table();
        $count_header = count($table_header);
        if ($count_header) {
            $table->setHeaders($table_header);
        }
        $table->setRows($table_rows);
        $table->display();
        echo PHP_EOL;
    } else {
        print_cli_data("Notice", "Table output suppressed due to piped output." . PHP_EOL);
    }
}
Example #9
0
 public function testTables()
 {
     $this->resetStreams();
     $suffix = \cli\Shell::isPiped() ? "_piped" : "";
     $this->assertTrue(is_numeric($columns = \cli\Shell::columns()));
     $headers = array('First Name', 'Last Name', 'City', 'State');
     $data = array(array('Maryam', 'Elliott', 'Elizabeth City', 'SD'), array('Jerry', 'Washington', 'Bessemer', 'ME'), array('Allegra', 'Hopkins', 'Altoona', 'ME'), array('Audrey', 'Oneil', 'Dalton', 'SK'));
     $table = new \cli\Table();
     $table->setRenderer(new \cli\table\Ascii());
     $table->setHeaders($headers);
     $table->setRows($data);
     $table->display();
     $output = $this->getStreams();
     $this->assertEquals("", $output['errors']);
     $this->assertEquals(file_get_contents("test/output/table_1"), $output['contents']);
     $this->resetStreams();
     $table->sort(1);
     $table->display();
     $output = $this->getStreams();
     $this->assertEquals("", $output['errors']);
     $this->assertEquals(file_get_contents("test/output/table_2"), $output['contents']);
     $this->resetStreams();
     foreach ($data as $k => $v) {
         $data[$k] = array_combine(array("name", "surname", "city", "state"), $v);
     }
     $renderer = new \cli\table\Ascii();
     $renderer->setCharacters(array("corner" => "x", "line" => "=", "border" => "!"));
     $table = new \cli\Table($data);
     $table->setRenderer($renderer);
     $table->sort("surname");
     $table->display();
     $output = $this->getStreams();
     $this->assertEquals("", $output['errors']);
     $this->assertEquals(file_get_contents("test/output/table_3"), $output['contents']);
     $this->assertEquals("", \cli\Colors::color("reset"));
     $this->assertEquals("foo\tbar", \cli\table\Tabular::row(array("foo", "bar")));
     $this->assertNull(\cli\table\Tabular::border());
     // test output
     $this->resetStreams();
     \cli\out("  \\cli\\out sends output to STDOUT\n");
     \cli\out("  It does not automatically append a new line\n");
     \cli\out("  It does accept any number of %s which are then %s to %s for formatting\n", 'arguments', 'passed', 'sprintf');
     \cli\out("  Alternatively, {:a} can use an {:b} as the second argument.\n\n", array('a' => 'you', 'b' => 'array'));
     \cli\err('  \\cli\\err sends output to STDERR');
     \cli\err('  It does automatically append a new line');
     \cli\err('  It does accept any number of %s which are then %s to %s for formatting', 'arguments', 'passed', 'sprintf');
     \cli\err("  Alternatively, {:a} can use an {:b} as the second argument.\n", array('a' => 'you', 'b' => 'array'));
     \cli\line('  \\cli\\line forwards to \\cli\\out for output');
     \cli\line('  It does automatically append a new line');
     \cli\line('  It does accept any number of %s which are then %s to %s for formatting', 'arguments', 'passed', 'sprintf');
     \cli\line("  Alternatively, {:a} can use an {:b} as the second argument.\n", array('a' => 'you', 'b' => 'array'));
     $output = $this->getStreams();
     $this->assertEquals(file_get_contents("test/output/out_errors"), $output['errors']);
     $this->assertEquals(file_get_contents("test/output/out_contents"), $output['contents']);
     $string = "";
     $string .= \cli\render('  \\cli\\err sends output to STDERR' . "\n");
     $string .= \cli\render('  It does automatically append a new line' . "\n");
     $string .= \cli\render('  It does accept any number of %s which are then %s to %s for formatting' . "\n", 'arguments', 'passed', 'sprintf');
     $string .= \cli\render("  Alternatively, {:a} can use an {:b} as the second argument.\n\n", array('a' => 'you', 'b' => 'array'));
     $this->assertEquals(file_get_contents("test/output/out_errors"), $string);
     $this->resetStreams();
     $in = tmpfile();
     fputs($in, "quit\n");
     fseek($in, 0);
     \cli\Streams::setStream("in", $in);
     $line = \cli\prompt("prompt", false, "# ");
     $output = $this->getStreams();
     $this->assertEquals("quit", $line);
     $this->assertEquals("", $output['errors']);
     $this->assertEquals("prompt# ", $output['contents']);
     fseek($in, 0);
     $this->assertEquals("quit", \cli\input());
     fclose($in);
 }
Example #10
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in all tables and will replace all
  * appearances of the old string with the new one.
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--precise]
  * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  */
 public function __invoke($args, $assoc_args)
 {
     global $wpdb;
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $dry_run = isset($assoc_args['dry-run']);
     $php_only = isset($assoc_args['precise']);
     $recurse_objects = isset($assoc_args['recurse-objects']);
     if (isset($assoc_args['skip-columns'])) {
         $skip_columns = explode(',', $assoc_args['skip-columns']);
     } else {
         $skip_columns = array();
     }
     // never mess with hashed passwords
     $skip_columns[] = 'user_pass';
     $tables = self::get_table_list($args, isset($assoc_args['network']));
     foreach ($tables as $table) {
         list($primary_keys, $columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (empty($primary_keys)) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $skip_columns)) {
                 continue;
             }
             if (!$php_only) {
                 $serialRow = $wpdb->get_row("SELECT * FROM `{$table}` WHERE `{$col}` REGEXP '^[aiO]:[1-9]' LIMIT 1");
             }
             if ($php_only || NULL !== $serialRow) {
                 $type = 'PHP';
                 $count = self::php_handle_col($col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects);
             } else {
                 $type = 'SQL';
                 $count = self::sql_handle_col($col, $table, $old, $new, $dry_run);
             }
             $report[] = array($table, $col, $count, $type);
             $total += $count;
         }
     }
     if (!WP_CLI::get_config('quiet')) {
         $table = new \cli\Table();
         $table->setHeaders(array('Table', 'Column', 'Replacements', 'Type'));
         $table->setRows($report);
         $table->display();
         if (!$dry_run) {
             WP_CLI::success("Made {$total} replacements.");
         }
     }
 }
Example #11
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in a selection of tables
  * and will replace all appearances of the old string with the new one.  The
  * default tables are those registered on the $wpdb object (usually
  * just WordPress core tables).
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to. Wildcards are supported, e.g. wp_\*_options or wp_post\?.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--precise]
  * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings. Defaults to true; pass --no-recurse-objects to disable.
  *
  * [--all-tables-with-prefix]
  * : Enable replacement on any tables that match the table prefix even if not registered on wpdb
  *
  * [--all-tables]
  * : Enable replacement on ALL tables in the database, regardless of the prefix, and even if not registered on $wpdb. Overrides --network and --all-tables-with-prefix.
  *
  * [--verbose]
  * : Prints rows to the console as they're updated.
  *
  * [--regex]
  * : Runs the search using a regular expression. Warning: search-replace will take about 15-20x longer when using --regex.
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  *
  *     # Turn your production database into a local database
  *     wp search-replace --url=example.com example.com example.dev wp_\*_options
  */
 public function __invoke($args, $assoc_args)
 {
     global $wpdb;
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $dry_run = \WP_CLI\Utils\get_flag_value($assoc_args, 'dry-run');
     $php_only = \WP_CLI\Utils\get_flag_value($assoc_args, 'precise');
     $recurse_objects = \WP_CLI\Utils\get_flag_value($assoc_args, 'recurse-objects', true);
     $verbose = \WP_CLI\Utils\get_flag_value($assoc_args, 'verbose');
     $regex = \WP_CLI\Utils\get_flag_value($assoc_args, 'regex');
     $skip_columns = explode(',', \WP_CLI\Utils\get_flag_value($assoc_args, 'skip-columns'));
     if ($old === $new && !$regex) {
         WP_CLI::warning("Replacement value '{$old}' is identical to search value '{$new}'. Skipping operation.");
         exit;
     }
     // never mess with hashed passwords
     $skip_columns[] = 'user_pass';
     // Determine how to limit the list of tables. Defaults to 'wordpress'
     $table_type = 'wordpress';
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'network')) {
         $table_type = 'network';
     }
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'all-tables-with-prefix')) {
         $table_type = 'all-tables-with-prefix';
     }
     if (\WP_CLI\Utils\get_flag_value($assoc_args, 'all-tables')) {
         $table_type = 'all-tables';
     }
     if (!empty($args)) {
         $new_tables = array();
         foreach ($args as $key => $table) {
             if (false !== strpos($table, '*') || false !== strpos($table, '?')) {
                 $expanded_tables = self::get_tables_for_glob($table);
                 if (empty($expanded_tables)) {
                     WP_CLI::error("Couldn't find any tables matching: {$table}");
                 }
                 $new_tables = array_merge($new_tables, $expanded_tables);
             } else {
                 $new_tables[] = $table;
             }
         }
         $args = $new_tables;
     }
     // Get the array of tables to work with. If there is anything left in $args, assume those are table names to use
     $tables = empty($args) ? self::get_table_list($table_type) : $args;
     foreach ($tables as $table) {
         list($primary_keys, $columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (empty($primary_keys)) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $skip_columns)) {
                 continue;
             }
             if (!$php_only) {
                 $serialRow = $wpdb->get_row("SELECT * FROM `{$table}` WHERE `{$col}` REGEXP '^[aiO]:[1-9]' LIMIT 1");
             }
             if ($php_only || $regex || NULL !== $serialRow) {
                 $type = 'PHP';
                 $count = self::php_handle_col($col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex);
             } else {
                 $type = 'SQL';
                 $count = self::sql_handle_col($col, $table, $old, $new, $dry_run, $verbose);
             }
             $report[] = array($table, $col, $count, $type);
             $total += $count;
         }
     }
     if (!WP_CLI::get_config('quiet')) {
         $table = new \cli\Table();
         $table->setHeaders(array('Table', 'Column', 'Replacements', 'Type'));
         $table->setRows($report);
         $table->display();
         if (!$dry_run) {
             $success_message = "Made {$total} replacements.";
             if ($total && 'Default' !== WP_CLI\Utils\wp_get_cache_type()) {
                 $success_message .= ' Please remember to flush your persistent object cache with `wp cache flush`.';
             }
             WP_CLI::success($success_message);
         }
     }
 }
Example #12
0
 /**
  * Search/replace strings in the database.
  *
  * ## DESCRIPTION
  *
  * This command will go through all rows in a selection of tables
  * and will replace all appearances of the old string with the new one.  The
  * default tables are those registered on the $wpdb object (usually
  * just WordPress core tables).
  *
  * It will correctly handle serialized values, and will not change primary key values.
  *
  * ## OPTIONS
  *
  * <old>
  * : The old string.
  *
  * <new>
  * : The new string.
  *
  * [<table>...]
  * : List of database tables to restrict the replacement to. Wildcards are supported, e.g. wp_\*_options or wp_post\?.
  *
  * [--network]
  * : Search/replace through all the tables in a multisite install.
  *
  * [--skip-columns=<columns>]
  * : Do not perform the replacement in the comma-separated columns.
  *
  * [--dry-run]
  * : Show report, but don't perform the changes.
  *
  * [--precise]
  * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data.
  *
  * [--recurse-objects]
  * : Enable recursing into objects to replace strings. Defaults to true; pass --no-recurse-objects to disable.
  *
  * [--all-tables-with-prefix]
  * : Enable replacement on any tables that match the table prefix even if not registered on wpdb
  *
  * [--all-tables]
  * : Enable replacement on ALL tables in the database, regardless of the prefix, and even if not registered on $wpdb. Overrides --network and --all-tables-with-prefix.
  *
  * [--verbose]
  * : Prints rows to the console as they're updated.
  *
  * [--regex]
  * : Runs the search using a regular expression. Warning: search-replace will take about 15-20x longer when using --regex.
  *
  * ## EXAMPLES
  *
  *     wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid
  *
  *     wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run
  *
  *     # Turn your production database into a local database
  *     wp search-replace --url=example.com example.com example.dev wp_\*_options
  */
 public function __invoke($args, $assoc_args)
 {
     global $wpdb;
     $old = array_shift($args);
     $new = array_shift($args);
     $total = 0;
     $report = array();
     $dry_run = \WP_CLI\Utils\get_flag_value($assoc_args, 'dry-run');
     $php_only = \WP_CLI\Utils\get_flag_value($assoc_args, 'precise');
     $recurse_objects = \WP_CLI\Utils\get_flag_value($assoc_args, 'recurse-objects', true);
     $verbose = \WP_CLI\Utils\get_flag_value($assoc_args, 'verbose');
     $regex = \WP_CLI\Utils\get_flag_value($assoc_args, 'regex');
     $skip_columns = explode(',', \WP_CLI\Utils\get_flag_value($assoc_args, 'skip-columns'));
     if ($old === $new && !$regex) {
         WP_CLI::warning("Replacement value '{$old}' is identical to search value '{$new}'. Skipping operation.");
         exit;
     }
     // never mess with hashed passwords
     $skip_columns[] = 'user_pass';
     // Get table names based on leftover $args or supplied $assoc_args
     $tables = \WP_CLI\Utils\wp_get_table_names($args, $assoc_args);
     foreach ($tables as $table) {
         list($primary_keys, $columns) = self::get_columns($table);
         // since we'll be updating one row at a time,
         // we need a primary key to identify the row
         if (empty($primary_keys)) {
             $report[] = array($table, '', 'skipped');
             continue;
         }
         foreach ($columns as $col) {
             if (in_array($col, $skip_columns)) {
                 continue;
             }
             if ($verbose) {
                 $this->start_time = microtime(true);
                 WP_CLI::log(sprintf('Checking: %s.%s', $table, $col));
             }
             if (!$php_only) {
                 $serialRow = $wpdb->get_row("SELECT * FROM `{$table}` WHERE `{$col}` REGEXP '^[aiO]:[1-9]' LIMIT 1");
             }
             if ($php_only || $regex || NULL !== $serialRow) {
                 $type = 'PHP';
                 $count = $this->php_handle_col($col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex);
             } else {
                 $type = 'SQL';
                 $count = $this->sql_handle_col($col, $table, $old, $new, $dry_run, $verbose);
             }
             $report[] = array($table, $col, $count, $type);
             $total += $count;
         }
     }
     if (!WP_CLI::get_config('quiet')) {
         $table = new \cli\Table();
         $table->setHeaders(array('Table', 'Column', 'Replacements', 'Type'));
         $table->setRows($report);
         $table->display();
         if (!$dry_run) {
             $success_message = "Made {$total} replacements.";
             if ($total && 'Default' !== WP_CLI\Utils\wp_get_cache_type()) {
                 $success_message .= ' Please remember to flush your persistent object cache with `wp cache flush`.';
             }
             WP_CLI::success($success_message);
         }
     }
 }
Example #13
0
 /**
  * Output user info in console
  * @param \stdClass $user
  */
 public static function displayUser($user)
 {
     \cli\line('%_' . $user->nick . '%n ' . $user->email . ' (#' . $user->id . ')');
     if (!empty($user->meta)) {
         $metaData = array();
         foreach ($user->meta as $name => $val) {
             if (is_bool($val)) {
                 $val = '%Wbool(' . ($val ? 'true' : 'false') . ')%n';
             } elseif (is_array($val)) {
                 $val = 'ARRAY: ' . json_encode($val) . ')';
             } elseif ($val instanceof \stdClass) {
                 $val = 'OBJECT: ' . json_encode((array) $val) . ')';
             }
             if (strlen($val) > 70) {
                 $val = substr($val, 0, 70) . '...';
             }
             $metaData[] = array($name, $val);
         }
         $table = new \cli\Table();
         $table->setHeaders(array('Meta name', 'Meta value'));
         $table->setRows($metaData);
         $table->display();
     }
 }