get_config() public static method

Provides access to --path=, --url=, and other values of the global configuration parameters. WP_CLI::log( 'The --url= value is: ' . WP_CLI::get_config( 'url' ) );
public static get_config ( string $key = null ) : mixed
$key string Get value for a specific global configuration parameter.
return mixed
 /**
  * Registers just a 'list' and 'run' command to the WC CLI
  * since we only want to enable certain actions on the system status
  * tools endpoints.
  */
 public static function register_commands()
 {
     global $wp_rest_server;
     $request = new WP_REST_Request('OPTIONS', '/wc/v1/system_status/tools');
     $response = $wp_rest_server->dispatch($request);
     $response_data = $response->get_data();
     $parent = "wc tool";
     $supported_commands = array('list', 'run');
     foreach ($supported_commands as $command) {
         $synopsis = array();
         if ('run' === $command) {
             $synopsis[] = array('name' => 'id', 'type' => 'positional', 'description' => __('The id for the resource.', 'woocommerce'), 'optional' => false);
             $method = 'update_item';
             $route = '/wc/v1/system_status/tools/(?P<id>[\\w-]+)';
         } elseif ('list' === $command) {
             $synopsis[] = array('name' => 'fields', 'type' => 'assoc', 'description' => __('Limit response to specific fields. Defaults to all fields.', 'woocommerce'), 'optional' => true);
             $synopsis[] = array('name' => 'field', 'type' => 'assoc', 'description' => __('Get the value of an individual field.', 'woocommerce'), 'optional' => true);
             $synopsis[] = array('name' => 'format', 'type' => 'assoc', 'description' => __('Render response in a particular format.', 'woocommerce'), 'optional' => true, 'default' => 'table', 'options' => array('table', 'json', 'csv', 'ids', 'yaml', 'count', 'headers', 'body', 'envelope'));
             $method = 'list_items';
             $route = '/wc/v1/system_status/tools';
         }
         $before_invoke = null;
         if (empty($command_args['when']) && WP_CLI::get_config('debug')) {
             $before_invoke = function () {
                 if (!defined('SAVEQUERIES')) {
                     define('SAVEQUERIES', true);
                 }
             };
         }
         $rest_command = new WC_CLI_REST_Command('system_status_tool', $route, $response_data['schema']);
         WP_CLI::add_command("{$parent} {$command}", array($rest_command, $method), array('synopsis' => $synopsis, 'when' => !empty($command_args['when']) ? $command_args['when'] : '', 'before_invoke' => $before_invoke));
     }
 }
Example #2
0
 public function run()
 {
     if (!function_exists('get_plugins')) {
         require_once \WP_CLI::get_config('path') . '/wp-admin/includes/plugin.php';
     }
     $all_plugins = get_plugins();
     $update = get_plugin_updates();
     $report = array();
     foreach ($all_plugins as $plugin_path => $data) {
         $slug = $plugin_path;
         if (stripos($plugin_path, '/')) {
             $slug = substr($plugin_path, 0, stripos($plugin_path, '/'));
         }
         $vulnerable = $this->is_vulnerable($slug, $data['Version']);
         $needs_update = 0;
         $available = '-';
         if (isset($update[$plugin_path])) {
             $needs_update = 1;
             $available = $update[$plugin_path]->update->new_version;
         }
         if (false === $vulnerable) {
             $vulnerable = "None";
         } else {
             $vulnerable = sprintf('<a href="https://wpvulndb.com/plugins/%s" target="_blank" >more info</a>', $slug);
         }
         $report[$slug] = array('slug' => $slug, 'installed' => (string) $data['Version'], 'available' => (string) $available, 'needs_update' => (string) $needs_update, 'vulnerable' => $vulnerable);
     }
     $this->alerts = $report;
 }
Example #3
0
function wp_debug_mode()
{
    if (\WP_CLI::get_config('debug')) {
        if (!defined('WP_DEBUG')) {
            define('WP_DEBUG', true);
        }
        error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
    } else {
        if (WP_DEBUG) {
            error_reporting(E_ALL);
            if (WP_DEBUG_DISPLAY) {
                ini_set('display_errors', 1);
            } elseif (null !== WP_DEBUG_DISPLAY) {
                ini_set('display_errors', 0);
            }
            if (WP_DEBUG_LOG) {
                ini_set('log_errors', 1);
                ini_set('error_log', WP_CONTENT_DIR . '/debug.log');
            }
        } else {
            error_reporting(E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR);
        }
        if (defined('XMLRPC_REQUEST') || defined('REST_REQUEST') || defined('DOING_AJAX') && DOING_AJAX) {
            @ini_set('display_errors', 0);
        }
    }
    // XDebug already sends errors to STDERR
    ini_set('display_errors', function_exists('xdebug_debug_zval') ? false : 'STDERR');
}
Example #4
0
function wp_debug_mode()
{
    if (\WP_CLI::get_config('debug')) {
        if (!defined('WP_DEBUG')) {
            define('WP_DEBUG', true);
        }
        error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
    } else {
        \wp_debug_mode();
    }
    // XDebug already sends errors to STDERR
    ini_set('display_errors', function_exists('xdebug_debug_zval') ? false : 'STDERR');
}
Example #5
0
 /**
  * Searches php files for the provided regex
  *
  * @param $dir string directory to start from
  * @param $regex string undelimited pattern to match
  *
  * @return array an array of matched files or empty if none found
  **/
 public static function search_php_files($dir, $regex)
 {
     $fs = self::load_fs();
     $finder = new Finder();
     // find all files ending in PHP
     $files = $finder->files()->in($dir)->name("*.php");
     $alerts = array();
     foreach ($files as $file) {
         if (\WP_CLI::get_config('debug')) {
             \WP_CLI::line(sprintf("-> %s", $file->getRelativePathname()));
         }
         if (preg_match('#' . $regex . '#s', $file->getContents()) !== 0) {
             $alerts[] = $file->getRelativePathname();
         }
     }
     return $alerts;
 }
 public function execute()
 {
     foreach ($this->callbacks() as $class => $object) {
         $object->init();
     }
     $files = $this->finder->files()->in($this->dir)->name("*.php");
     foreach ($files as $file) {
         if (\WP_CLI::get_config('debug')) {
             \WP_CLI::line(sprintf("-> %s", $file->getRelativePathname()));
         }
         foreach ($this->callbacks() as $class => $object) {
             $object->run($file);
         }
     }
     foreach ($this->callbacks() as $class => $object) {
         $object->message(Messenger::instance());
     }
 }
 /**
  * Download and install theme unit test datafile
  * 
  * @param string $option  --data value
  * @since 0.2
  */
 private function import_test_data($option = NULL)
 {
     if ('skip' === $option) {
         return;
     }
     $option = NULL === $option ? 'unit-test' : $option;
     $datafiles = array('unit-test' => 'https://wpcom-themes.svn.automattic.com/demo/theme-unit-test-data.xml', 'wpcom-theme' => 'https://wpcom-themes.svn.automattic.com/demo/wordpress-com-theme-test.xml', 'wpcom-demo' => 'https://wpcom-themes.svn.automattic.com/demo/demo-data.xml', 'wptest' => 'https://raw.github.com/manovotny/wptest/master/wptest.xml');
     $keys = array_values(array_keys($datafiles));
     if (in_array($option, $keys)) {
         $download_url = $datafiles[$option];
     } elseif (false != $option) {
         $download_url = $option;
     } else {
         WP_CLI::error('Missing WXR path/URL.');
     }
     WP_CLI::line('WXR data URL: ' . $download_url);
     $silent = WP_CLI::get_config('quiet') ? '--silent ' : '';
     $cmdline = "curl -f {$silent} {$download_url} -o /tmp/wp-cli-test-data.xml";
     WP_CLI::launch($cmdline);
     WP_CLI::launch('wp import /tmp/wp-cli-test-data.xml --authors=skip');
 }
    /**
     * Do a REST Request
     *
     * @param string $method
     *
     */
    private function do_request($method, $route, $assoc_args)
    {
        if (!defined('REST_REQUEST')) {
            define('REST_REQUEST', true);
        }
        $request = new WP_REST_Request($method, $route);
        if (in_array($method, array('POST', 'PUT'))) {
            $request->set_body_params($assoc_args);
        } else {
            foreach ($assoc_args as $key => $value) {
                $request->set_param($key, $value);
            }
        }
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $original_queries = is_array($GLOBALS['wpdb']->queries) ? array_keys($GLOBALS['wpdb']->queries) : array();
        }
        $response = rest_do_request($request);
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $performed_queries = array();
            foreach ((array) $GLOBALS['wpdb']->queries as $key => $query) {
                if (in_array($key, $original_queries)) {
                    continue;
                }
                $performed_queries[] = $query;
            }
            usort($performed_queries, function ($a, $b) {
                if ($a[1] === $b[1]) {
                    return 0;
                }
                return $a[1] > $b[1] ? -1 : 1;
            });
            $query_count = count($performed_queries);
            $query_total_time = 0;
            foreach ($performed_queries as $query) {
                $query_total_time += $query[1];
            }
            $slow_query_message = '';
            if ($performed_queries && 'wc' === WP_CLI::get_config('debug')) {
                $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL;
                foreach ($performed_queries as $i => $query) {
                    $i++;
                    $bits = explode(', ', $query[2]);
                    $backtrace = implode(', ', array_slice($bits, 13));
                    $seconds = round($query[1], 6);
                    $slow_query_message .= <<<EOT
{$i}:
- {$seconds} seconds
- {$backtrace}
- {$query[0]}
EOT;
                    $slow_query_message .= PHP_EOL;
                }
            } elseif ('wc' !== WP_CLI::get_config('debug')) {
                $slow_query_message = '. Use --debug=wc to see all queries.';
            }
            $query_total_time = round($query_total_time, 6);
            WP_CLI::debug("wc command executed {$query_count} queries in {$query_total_time} seconds{$slow_query_message}", 'wc');
        }
        if ($error = $response->as_error()) {
            WP_CLI::error($error);
        }
        return array($response->get_status(), $response->get_data(), $response->get_headers());
    }
 /**
  * Invoke the subcommand with the supplied arguments.
  * Given a --prompt argument, interactively request input
  * from the end user.
  *
  * @param array $args
  * @param array $assoc_args
  */
 public function invoke($args, $assoc_args, $extra_args)
 {
     if (\WP_CLI::get_config('prompt')) {
         list($args, $assoc_args) = $this->prompt_args($args, $assoc_args);
     }
     $to_unset = $this->validate_args($args, $assoc_args, $extra_args);
     foreach ($to_unset as $key) {
         unset($assoc_args[$key]);
     }
     $path = get_path($this->get_parent());
     \WP_CLI::do_hook('before_invoke:' . implode(' ', array_slice($path, 1)));
     call_user_func($this->when_invoked, $args, array_merge($extra_args, $assoc_args));
 }
Example #10
0
 function apache_get_modules()
 {
     return WP_CLI::get_config('apache_modules');
 }
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);
         }
     }
 }
 /**
  * Generates command information and tells WP CLI about all
  * commands avaiable from a route.
  *
  * @param string $rest_command
  * @param string $route
  * @param array  $route_data
  * @param array  $command_args
  */
 private static function register_route_commands($rest_command, $route, $route_data, $command_args = array())
 {
     $parent = "wc {$route_data['schema']['title']}";
     $supported_commands = array();
     // Get a list of supported commands for each route.
     foreach ($route_data['endpoints'] as $endpoint) {
         $parsed_args = preg_match_all('#\\([^\\)]+\\)#', $route, $matches);
         $first_match = $matches[0];
         $resource_id = !empty($matches[0]) ? array_pop($matches[0]) : null;
         $trimmed_route = rtrim($route);
         $is_singular = $resource_id === substr($trimmed_route, -strlen($resource_id));
         if (!$is_singular) {
             $resource_id = $first_match;
         }
         $command = '';
         // List a collection
         if (array('GET') == $endpoint['methods'] && !$is_singular) {
             $supported_commands['list'] = !empty($endpoint['args']) ? $endpoint['args'] : array();
         }
         // Create a specific resource
         if (array('POST') == $endpoint['methods'] && !$is_singular) {
             $supported_commands['create'] = !empty($endpoint['args']) ? $endpoint['args'] : array();
         }
         // Get a specific resource
         if (array('GET') == $endpoint['methods'] && $is_singular) {
             $supported_commands['get'] = !empty($endpoint['args']) ? $endpoint['args'] : array();
         }
         // Update a specific resource
         if (in_array('POST', $endpoint['methods']) && $is_singular) {
             $supported_commands['update'] = !empty($endpoint['args']) ? $endpoint['args'] : array();
         }
         // Delete a specific resource
         if (array('DELETE') == $endpoint['methods'] && $is_singular) {
             $supported_commands['delete'] = !empty($endpoint['args']) ? $endpoint['args'] : array();
         }
     }
     foreach ($supported_commands as $command => $endpoint_args) {
         $synopsis = array();
         $arg_regs = array();
         if (strpos($route, '<product_id>') !== false) {
             $synopsis[] = array('name' => 'product_id', 'type' => 'positional', 'description' => __('Product ID.', 'woocommerce'));
         }
         if (strpos($route, '<customer_id>') !== false) {
             $synopsis[] = array('name' => 'customer_id', 'type' => 'positional', 'description' => __('Customer ID.', 'woocommerce'));
         }
         if (strpos($route, '<order_id>') !== false) {
             $synopsis[] = array('name' => 'order_id', 'type' => 'positional', 'description' => __('Order ID.', 'woocommerce'));
         }
         if (strpos($route, '<refund_id>') !== false) {
             $synopsis[] = array('name' => 'refund_id', 'type' => 'positional', 'description' => __('Refund ID.', 'woocommerce'));
         }
         if (in_array($command, array('delete', 'get', 'update'))) {
             $synopsis[] = array('name' => 'id', 'type' => 'positional', 'description' => __('The id for the resource.', 'woocommerce'), 'optional' => false);
         }
         foreach ($endpoint_args as $name => $args) {
             $arg_regs[] = array('name' => $name, 'type' => 'assoc', 'description' => !empty($args['description']) ? $args['description'] : '', 'optional' => empty($args['required']) ? true : false);
         }
         foreach ($arg_regs as $arg_reg) {
             $synopsis[] = $arg_reg;
         }
         if (in_array($command, array('list', 'get'))) {
             $synopsis[] = array('name' => 'fields', 'type' => 'assoc', 'description' => __('Limit response to specific fields. Defaults to all fields.', 'woocommerce'), 'optional' => true);
             $synopsis[] = array('name' => 'field', 'type' => 'assoc', 'description' => __('Get the value of an individual field.', 'woocommerce'), 'optional' => true);
             $synopsis[] = array('name' => 'format', 'type' => 'assoc', 'description' => __('Render response in a particular format.', 'woocommerce'), 'optional' => true, 'default' => 'table', 'options' => array('table', 'json', 'csv', 'ids', 'yaml', 'count', 'headers', 'body', 'envelope'));
         }
         if (in_array($command, array('create', 'update', 'delete'))) {
             $synopsis[] = array('name' => 'porcelain', 'type' => 'flag', 'description' => __('Output just the id when the operation is successful.', 'woocommerce'), 'optional' => true);
         }
         $methods = array('list' => 'list_items', 'create' => 'create_item', 'delete' => 'delete_item', 'get' => 'get_item', 'update' => 'update_item');
         $before_invoke = null;
         if (empty($command_args['when']) && \WP_CLI::get_config('debug')) {
             $before_invoke = function () {
                 if (!defined('SAVEQUERIES')) {
                     define('SAVEQUERIES', true);
                 }
             };
         }
         WP_CLI::add_command("{$parent} {$command}", array($rest_command, $methods[$command]), array('synopsis' => $synopsis, 'when' => !empty($command_args['when']) ? $command_args['when'] : '', 'before_invoke' => $before_invoke));
     }
 }
Example #13
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 #14
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 #15
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);
         }
     }
 }
 /**
  * Lint your WordPress code using WP CLI.
  *
  * ### Config
  * You can add the path to the `phpcs` bin to use in WP CLI's config file and/or the standard that should be used.
  *
  * Example of `~/.wp-cli/config.yml`:
  *
  *     lint:
  *       phpcs: /path/to/phpcs
  *       standard: `WordPress-Extra`
  *
  * ### Options
  *
  * #### `[<directory>]`
  * The directory to lint code in. **Default: '__DIR__'**
  *
  * #### `[--standard=<standard>]`
  * The standard to use when running `phpcs`. **Default: 'WordPress-Core'**
  *
  * ### Examples
  *
  *     wp lint
  *     wp lint path/to/code --standard=WordPress-Extra
  *
  * @param array $args
  * @param array $options
  *
  * @when before_wp_load
  */
 public function __invoke(array $args = [], array $options = [])
 {
     if (empty($args)) {
         $args[] = getcwd();
     }
     if (!file_exists($args[0])) {
         WP_CLI::error(sprintf('The file "%s" does not exist', $args[0]));
     }
     $root_path = rtrim(ABSPATH, '/');
     $phpcs_bin = $this->get_phpcs_bin($root_path);
     $phpcs_standard = $this->get_phpcs_standard($root_path, $options);
     $command_args = '-s --extensions=php --standard=' . $phpcs_standard;
     $command = sprintf('%s %s %s', $phpcs_bin, $command_args, $args[0]);
     if (WP_CLI::get_config('debug')) {
         echo sprintf("Running command: %s \n", $command);
     }
     exec($command, $output, $status);
     if (count($output) === 1 && strpos($output[0], 'ERROR') === false) {
         $output = [];
     }
     foreach ($output as $line) {
         if (strpos($output[0], 'ERROR') === false) {
             WP_CLI::log($line);
         } else {
             WP_CLI::error(str_replace('ERROR: ', '', $line));
         }
     }
     if ($status !== 0) {
         WP_CLI::error('Sorry, but your code does not follow the code style. Please fix before commit.');
     } else {
         WP_CLI::success('Good job! Your code follows the code style.');
     }
 }
Example #17
0
 /**
  * Invoke the subcommand with the supplied arguments.
  * Given a --prompt argument, interactively request input
  * from the end user.
  *
  * @param array $args
  * @param array $assoc_args
  */
 public function invoke($args, $assoc_args, $extra_args)
 {
     static $prompted_once = false;
     if (\WP_CLI::get_config('prompt') && !$prompted_once) {
         list($args, $assoc_args) = $this->prompt_args($args, $assoc_args);
         $prompted_once = true;
     }
     list($to_unset, $args, $assoc_args, $extra_args) = $this->validate_args($args, $assoc_args, $extra_args);
     foreach ($to_unset as $key) {
         unset($assoc_args[$key]);
     }
     $path = get_path($this->get_parent());
     $parent = implode(' ', array_slice($path, 1));
     $cmd = $parent . ' ' . $this->name;
     WP_CLI::do_hook("before_invoke:{$parent}");
     WP_CLI::do_hook("before_invoke:{$cmd}");
     call_user_func($this->when_invoked, $args, array_merge($extra_args, $assoc_args));
     WP_CLI::do_hook("after_invoke:{$parent}");
     WP_CLI::do_hook("after_invoke:{$cmd}");
 }
Example #18
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.");
         }
     }
 }